Commit fc295adf authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

Implement platform/fonts part of 'font-variant-east-asian'

This patch implements platform/fonts part of the CSS
'font-variant-east-asian' property.

The property is not exposed until CSS parser part is done in CL:651528.

Bug: 755462
Change-Id: I9194f67b111aeb4dd15bf711a0d928937001631e
Reviewed-on: https://chromium-review.googlesource.com/652066
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarDominik Röttsches <drott@chromium.org>
Cr-Commit-Position: refs/heads/master@{#499995}
parent 2335c041
......@@ -727,6 +727,7 @@ component("platform") {
"fonts/FontSelector.h",
"fonts/FontSelectorClient.h",
"fonts/FontSmoothingMode.h",
"fonts/FontVariantEastAsian.h",
"fonts/FontVariantNumeric.h",
"fonts/FontWidthVariant.h",
"fonts/GenericFontFamilySettings.cpp",
......
......@@ -164,6 +164,11 @@ void FontDescription::SetVariantCaps(FontVariantCaps variant_caps) {
UpdateTypesettingFeatures();
}
void FontDescription::SetVariantEastAsian(
const FontVariantEastAsian variant_east_asian) {
fields_.variant_east_asian_ = variant_east_asian.fields_as_unsigned_;
}
void FontDescription::SetVariantLigatures(const VariantLigatures& ligatures) {
fields_.common_ligatures_state_ = ligatures.common;
fields_.discretionary_ligatures_state_ = ligatures.discretionary;
......
......@@ -34,6 +34,7 @@
#include "platform/fonts/FontOrientation.h"
#include "platform/fonts/FontSelectionTypes.h"
#include "platform/fonts/FontSmoothingMode.h"
#include "platform/fonts/FontVariantEastAsian.h"
#include "platform/fonts/FontVariantNumeric.h"
#include "platform/fonts/FontWidthVariant.h"
#include "platform/fonts/TextRenderingMode.h"
......@@ -164,6 +165,10 @@ class PLATFORM_EXPORT FontDescription {
Family().Family() == FontFamilyNames::webkit_monospace;
}
Kerning GetKerning() const { return static_cast<Kerning>(fields_.kerning_); }
FontVariantEastAsian GetVariantEastAsian() const {
return FontVariantEastAsian::InitializeFromUnsigned(
fields_.variant_east_asian_);
}
VariantLigatures GetVariantLigatures() const;
FontVariantNumeric VariantNumeric() const {
return FontVariantNumeric::InitializeFromUnsigned(fields_.variant_numeric_);
......@@ -243,6 +248,7 @@ class PLATFORM_EXPORT FontDescription {
void SetStretch(FontSelectionValue s) { font_selection_request_.width = s; }
void SetVariantCaps(FontVariantCaps);
void SetVariantEastAsian(const FontVariantEastAsian);
void SetVariantLigatures(const VariantLigatures&);
void SetVariantNumeric(const FontVariantNumeric&);
void SetIsAbsoluteSize(bool s) { fields_.is_absolute_size_ = s; }
......@@ -380,6 +386,7 @@ class PLATFORM_EXPORT FontDescription {
unsigned subpixel_text_position_ : 1;
unsigned typesetting_features_ : 3;
unsigned variant_numeric_ : 8;
unsigned variant_east_asian_ : 6;
mutable unsigned subpixel_ascent_descent_ : 1;
};
......
// Copyright 2017 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 FontVariantEastAsian_h
#define FontVariantEastAsian_h
#include "platform/wtf/Allocator.h"
namespace blink {
class FontVariantEastAsian {
STACK_ALLOCATED();
public:
enum EastAsianForm {
kNormalForm,
kJis78,
kJis83,
kJis90,
kJis04,
kSimplified,
kTraditional
// Ensure |BitFields| has enough bits when adding values.
};
enum EastAsianWidth {
kNormalWidth,
kFullWidth,
kProportionalWidth
// Ensure |BitFields| has enough bits when adding values.
};
FontVariantEastAsian() : fields_as_unsigned_(0) {}
static FontVariantEastAsian InitializeFromUnsigned(unsigned init_value) {
return FontVariantEastAsian(init_value);
}
EastAsianForm Form() const {
return static_cast<EastAsianForm>(fields_.form_);
}
EastAsianWidth Width() const {
return static_cast<EastAsianWidth>(fields_.width_);
}
bool Ruby() const { return fields_.ruby_; }
void SetForm(EastAsianForm form) { fields_.form_ = form; };
void SetWidth(EastAsianWidth width) { fields_.width_ = width; };
void SetRuby(bool ruby) { fields_.ruby_ = ruby; };
bool IsAllNormal() const { return !fields_as_unsigned_; }
bool operator==(const FontVariantEastAsian& other) const {
return fields_as_unsigned_ == other.fields_as_unsigned_;
}
private:
FontVariantEastAsian(unsigned init_value) : fields_as_unsigned_(init_value) {}
struct BitFields {
unsigned form_ : 3;
unsigned width_ : 2;
unsigned ruby_ : 1;
// Ensure |FontDescription| has enough bits when adding values.
};
union {
BitFields fields_;
unsigned fields_as_unsigned_;
};
static_assert(sizeof(BitFields) == sizeof(unsigned),
"Mapped union types must match in size.");
// Used in setVariant to store the value in m_fields.m_variantNumeric;
friend class FontDescription;
};
} // namespace blink
#endif // FontVariantEastAsian_h
......@@ -411,6 +411,8 @@ hb_feature_t CreateFeature(hb_tag_t tag, uint32_t value = 0) {
return {tag, value, 0 /* start */, static_cast<unsigned>(-1) /* end */};
}
// TODO(kojii): crbug.com/762493 This list is getting long enough to extract out
// of HarfBuzzShaper.cpp.
void SetFontFeatures(const Font* font, FeaturesVector* features) {
const FontDescription& description = font->GetFontDescription();
......@@ -492,6 +494,58 @@ void SetFontFeatures(const Font* font, FeaturesVector* features) {
break;
}
// font-variant-east-asian:
const FontVariantEastAsian east_asian = description.GetVariantEastAsian();
if (UNLIKELY(!east_asian.IsAllNormal())) {
static hb_feature_t jp78 = CreateFeature(HB_TAG('j', 'p', '7', '8'), 1);
static hb_feature_t jp83 = CreateFeature(HB_TAG('j', 'p', '8', '3'), 1);
static hb_feature_t jp90 = CreateFeature(HB_TAG('j', 'p', '9', '0'), 1);
static hb_feature_t jp04 = CreateFeature(HB_TAG('j', 'p', '0', '4'), 1);
static hb_feature_t smpl = CreateFeature(HB_TAG('s', 'm', 'p', 'l'), 1);
static hb_feature_t trad = CreateFeature(HB_TAG('t', 'r', 'a', 'd'), 1);
switch (east_asian.Form()) {
case FontVariantEastAsian::kNormalForm:
break;
case FontVariantEastAsian::kJis78:
features->push_back(jp78);
break;
case FontVariantEastAsian::kJis83:
features->push_back(jp83);
break;
case FontVariantEastAsian::kJis90:
features->push_back(jp90);
break;
case FontVariantEastAsian::kJis04:
features->push_back(jp04);
break;
case FontVariantEastAsian::kSimplified:
features->push_back(smpl);
break;
case FontVariantEastAsian::kTraditional:
features->push_back(trad);
break;
default:
NOTREACHED();
}
static hb_feature_t fwid = CreateFeature(HB_TAG('f', 'w', 'i', 'd'), 1);
static hb_feature_t pwid = CreateFeature(HB_TAG('p', 'w', 'i', 'd'), 1);
switch (east_asian.Width()) {
case FontVariantEastAsian::kNormalWidth:
break;
case FontVariantEastAsian::kFullWidth:
features->push_back(fwid);
break;
case FontVariantEastAsian::kProportionalWidth:
features->push_back(pwid);
break;
default:
NOTREACHED();
}
static hb_feature_t ruby = CreateFeature(HB_TAG('r', 'u', 'b', 'y'), 1);
if (east_asian.Ruby())
features->push_back(ruby);
}
// font-variant-numeric:
static hb_feature_t lnum = CreateFeature(HB_TAG('l', 'n', 'u', 'm'), 1);
if (description.VariantNumeric().NumericFigureValue() ==
......
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