Commit 338670cb authored by Koji Ishii's avatar Koji Ishii Committed by Chromium LUCI CQ

Extract `CreateFeature` to a new class

In order to make the function to be more testable and easier
to maintian.

This patch has no behavior changes.

Bug: 762493
Change-Id: Ia0e4838bfa3fec644067dea1edf0e53915931153
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2612630
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarDominik Röttsches <drott@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842906}
parent 451c64aa
......@@ -659,6 +659,8 @@ component("platform") {
"fonts/shaping/caching_word_shaper.h",
"fonts/shaping/case_mapping_harfbuzz_buffer_filler.cc",
"fonts/shaping/case_mapping_harfbuzz_buffer_filler.h",
"fonts/shaping/font_features.cc",
"fonts/shaping/font_features.h",
"fonts/shaping/glyph_bounds_accumulator.h",
"fonts/shaping/harfbuzz_face.cc",
"fonts/shaping/harfbuzz_face.h",
......
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/fonts/shaping/font_features.h"
#include "third_party/blink/renderer/platform/fonts/font.h"
namespace blink {
namespace {
constexpr hb_feature_t CreateFeature(hb_tag_t tag, uint32_t value = 0) {
return {tag, value, 0 /* start */, static_cast<unsigned>(-1) /* end */};
}
constexpr hb_feature_t CreateFeature(char c1,
char c2,
char c3,
char c4,
uint32_t value = 0) {
return CreateFeature(HB_TAG(c1, c2, c3, c4), value);
}
} // namespace
void FontFeatures::Initialize(const Font& font) {
DCHECK(IsEmpty());
const FontDescription& description = font.GetFontDescription();
constexpr hb_feature_t no_kern = CreateFeature('k', 'e', 'r', 'n');
constexpr hb_feature_t no_vkrn = CreateFeature('v', 'k', 'r', 'n');
switch (description.GetKerning()) {
case FontDescription::kNormalKerning:
// kern/vkrn are enabled by default in HarfBuzz
break;
case FontDescription::kNoneKerning:
Append(description.IsVerticalAnyUpright() ? no_vkrn : no_kern);
break;
case FontDescription::kAutoKerning:
break;
}
{
bool default_is_off = description.TextRendering() == blink::kOptimizeSpeed;
bool letter_spacing = description.LetterSpacing() != 0;
constexpr auto normal = FontDescription::kNormalLigaturesState;
constexpr auto enabled = FontDescription::kEnabledLigaturesState;
constexpr auto disabled = FontDescription::kDisabledLigaturesState;
// clig and liga are on by default in HarfBuzz
constexpr hb_feature_t no_clig = CreateFeature('c', 'l', 'i', 'g');
constexpr hb_feature_t no_liga = CreateFeature('l', 'i', 'g', 'a');
auto common = description.CommonLigaturesState();
if (letter_spacing ||
(common == disabled || (common == normal && default_is_off))) {
Append(no_liga);
Append(no_clig);
}
// dlig is off by default in HarfBuzz
constexpr hb_feature_t dlig = CreateFeature('d', 'l', 'i', 'g', 1);
auto discretionary = description.DiscretionaryLigaturesState();
if (!letter_spacing && discretionary == enabled) {
Append(dlig);
}
// hlig is off by default in HarfBuzz
constexpr hb_feature_t hlig = CreateFeature('h', 'l', 'i', 'g', 1);
auto historical = description.HistoricalLigaturesState();
if (!letter_spacing && historical == enabled) {
Append(hlig);
}
// calt is on by default in HarfBuzz
constexpr hb_feature_t no_calt = CreateFeature('c', 'a', 'l', 't');
auto contextual = description.ContextualLigaturesState();
if (letter_spacing ||
(contextual == disabled || (contextual == normal && default_is_off))) {
Append(no_calt);
}
}
static constexpr hb_feature_t hwid = CreateFeature('h', 'w', 'i', 'd', 1);
static constexpr hb_feature_t twid = CreateFeature('t', 'w', 'i', 'd', 1);
static constexpr hb_feature_t qwid = CreateFeature('q', 'w', 'i', 'd', 1);
switch (description.WidthVariant()) {
case kHalfWidth:
Append(hwid);
break;
case kThirdWidth:
Append(twid);
break;
case kQuarterWidth:
Append(qwid);
break;
case kRegularWidth:
break;
}
// font-variant-east-asian:
const FontVariantEastAsian east_asian = description.VariantEastAsian();
if (UNLIKELY(!east_asian.IsAllNormal())) {
static constexpr hb_feature_t jp78 = CreateFeature('j', 'p', '7', '8', 1);
static constexpr hb_feature_t jp83 = CreateFeature('j', 'p', '8', '3', 1);
static constexpr hb_feature_t jp90 = CreateFeature('j', 'p', '9', '0', 1);
static constexpr hb_feature_t jp04 = CreateFeature('j', 'p', '0', '4', 1);
static constexpr hb_feature_t smpl = CreateFeature('s', 'm', 'p', 'l', 1);
static constexpr hb_feature_t trad = CreateFeature('t', 'r', 'a', 'd', 1);
switch (east_asian.Form()) {
case FontVariantEastAsian::kNormalForm:
break;
case FontVariantEastAsian::kJis78:
Append(jp78);
break;
case FontVariantEastAsian::kJis83:
Append(jp83);
break;
case FontVariantEastAsian::kJis90:
Append(jp90);
break;
case FontVariantEastAsian::kJis04:
Append(jp04);
break;
case FontVariantEastAsian::kSimplified:
Append(smpl);
break;
case FontVariantEastAsian::kTraditional:
Append(trad);
break;
default:
NOTREACHED();
}
static constexpr hb_feature_t fwid = CreateFeature('f', 'w', 'i', 'd', 1);
static constexpr hb_feature_t pwid = CreateFeature('p', 'w', 'i', 'd', 1);
switch (east_asian.Width()) {
case FontVariantEastAsian::kNormalWidth:
break;
case FontVariantEastAsian::kFullWidth:
Append(fwid);
break;
case FontVariantEastAsian::kProportionalWidth:
Append(pwid);
break;
default:
NOTREACHED();
}
static constexpr hb_feature_t ruby = CreateFeature('r', 'u', 'b', 'y', 1);
if (east_asian.Ruby())
Append(ruby);
}
// font-variant-numeric:
static constexpr hb_feature_t lnum = CreateFeature('l', 'n', 'u', 'm', 1);
if (description.VariantNumeric().NumericFigureValue() ==
FontVariantNumeric::kLiningNums)
Append(lnum);
static constexpr hb_feature_t onum = CreateFeature('o', 'n', 'u', 'm', 1);
if (description.VariantNumeric().NumericFigureValue() ==
FontVariantNumeric::kOldstyleNums)
Append(onum);
static constexpr hb_feature_t pnum = CreateFeature('p', 'n', 'u', 'm', 1);
if (description.VariantNumeric().NumericSpacingValue() ==
FontVariantNumeric::kProportionalNums)
Append(pnum);
static constexpr hb_feature_t tnum = CreateFeature('t', 'n', 'u', 'm', 1);
if (description.VariantNumeric().NumericSpacingValue() ==
FontVariantNumeric::kTabularNums)
Append(tnum);
static constexpr hb_feature_t afrc = CreateFeature('a', 'f', 'r', 'c', 1);
if (description.VariantNumeric().NumericFractionValue() ==
FontVariantNumeric::kStackedFractions)
Append(afrc);
static constexpr hb_feature_t frac = CreateFeature('f', 'r', 'a', 'c', 1);
if (description.VariantNumeric().NumericFractionValue() ==
FontVariantNumeric::kDiagonalFractions)
Append(frac);
static constexpr hb_feature_t ordn = CreateFeature('o', 'r', 'd', 'n', 1);
if (description.VariantNumeric().OrdinalValue() ==
FontVariantNumeric::kOrdinalOn)
Append(ordn);
static constexpr hb_feature_t zero = CreateFeature('z', 'e', 'r', 'o', 1);
if (description.VariantNumeric().SlashedZeroValue() ==
FontVariantNumeric::kSlashedZeroOn)
Append(zero);
FontFeatureSettings* settings = description.FeatureSettings();
if (!settings)
return;
// TODO(drott): crbug.com/450619 Implement feature resolution instead of
// just appending the font-feature-settings.
for (const FontFeature& setting : *settings) {
const hb_feature_t feature = CreateFeature(setting.Tag(), setting.Value());
Append(feature);
}
}
} // namespace blink
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_FONT_FEATURES_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_FONT_FEATURES_H_
#include <hb.h>
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class Font;
// Represents a list of OpenType font feature settings.
class FontFeatures {
STACK_ALLOCATED();
public:
// Initialize the list from |Font|.
void Initialize(const Font&);
wtf_size_t size() const { return features_.size(); }
bool IsEmpty() const { return features_.IsEmpty(); }
const hb_feature_t* data() const { return features_.data(); }
void Append(const hb_feature_t& feature) { features_.push_back(feature); }
void Insert(const hb_feature_t& feature) { features_.push_front(feature); }
void EraseAt(wtf_size_t position, wtf_size_t length) {
features_.EraseAt(position, length);
}
private:
Vector<hb_feature_t, 6> features_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_FONT_FEATURES_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment