1 /*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkFont.h"
9 #include "SkTypeface.h"
10 #include "SkUtils.h"
11
SkFont(sk_sp<SkTypeface> face,SkScalar size,SkScalar scaleX,SkScalar skewX,MaskType mt,uint32_t flags)12 SkFont::SkFont(sk_sp<SkTypeface> face, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType mt,
13 uint32_t flags)
14 : fTypeface(face ? std::move(face) : SkTypeface::MakeDefault())
15 , fSize(size)
16 , fScaleX(scaleX)
17 , fSkewX(skewX)
18 , fFlags(flags)
19 , fMaskType(SkToU8(mt))
20 {
21 SkASSERT(size > 0);
22 SkASSERT(scaleX > 0);
23 SkASSERT(SkScalarIsFinite(skewX));
24 SkASSERT(0 == (flags & ~kAllFlags));
25 }
26
Make(sk_sp<SkTypeface> face,SkScalar size,SkScalar scaleX,SkScalar skewX,MaskType mt,uint32_t flags)27 sk_sp<SkFont> SkFont::Make(sk_sp<SkTypeface> face, SkScalar size, SkScalar scaleX, SkScalar skewX,
28 MaskType mt, uint32_t flags) {
29 if (size <= 0 || !SkScalarIsFinite(size)) {
30 return nullptr;
31 }
32 if (scaleX <= 0 || !SkScalarIsFinite(scaleX)) {
33 return nullptr;
34 }
35 if (!SkScalarIsFinite(skewX)) {
36 return nullptr;
37 }
38 flags &= kAllFlags;
39 return sk_sp<SkFont>(new SkFont(std::move(face), size, scaleX, skewX, mt, flags));
40 }
41
Make(sk_sp<SkTypeface> face,SkScalar size,MaskType mt,uint32_t flags)42 sk_sp<SkFont> SkFont::Make(sk_sp<SkTypeface> face, SkScalar size, MaskType mt, uint32_t flags) {
43 return SkFont::Make(std::move(face), size, 1, 0, mt, flags);
44 }
45
makeWithSize(SkScalar newSize) const46 sk_sp<SkFont> SkFont::makeWithSize(SkScalar newSize) const {
47 return SkFont::Make(sk_ref_sp(this->getTypeface()), newSize, this->getScaleX(),
48 this->getSkewX(), this->getMaskType(), this->getFlags());
49 }
50
makeWithFlags(uint32_t newFlags) const51 sk_sp<SkFont> SkFont::makeWithFlags(uint32_t newFlags) const {
52 return SkFont::Make(sk_ref_sp(this->getTypeface()), this->getSize(), this->getScaleX(),
53 this->getSkewX(), this->getMaskType(), newFlags);
54 }
55 ///////////////////////////////////////////////////////////////////////////////////////////////////
56
textToGlyphs(const void * text,size_t byteLength,SkTextEncoding encoding,uint16_t glyphs[],int maxGlyphCount) const57 int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
58 uint16_t glyphs[], int maxGlyphCount) const {
59 if (0 == byteLength) {
60 return 0;
61 }
62
63 SkASSERT(text);
64
65 int count = 0; // fix uninitialized warning (even though the switch is complete!)
66
67 switch (encoding) {
68 case kUTF8_SkTextEncoding:
69 count = SkUTF8_CountUnichars((const char*)text, byteLength);
70 break;
71 case kUTF16_SkTextEncoding:
72 count = SkUTF16_CountUnichars((const uint16_t*)text, byteLength);
73 break;
74 case kUTF32_SkTextEncoding:
75 count = SkToInt(byteLength >> 2);
76 break;
77 case kGlyphID_SkTextEncoding:
78 count = SkToInt(byteLength >> 1);
79 break;
80 }
81 if (!glyphs) {
82 return count;
83 }
84
85 // TODO: unify/eliminate SkTypeface::Encoding with SkTextEncoding
86 SkTypeface::Encoding typefaceEncoding;
87 switch (encoding) {
88 case kUTF8_SkTextEncoding:
89 typefaceEncoding = SkTypeface::kUTF8_Encoding;
90 break;
91 case kUTF16_SkTextEncoding:
92 typefaceEncoding = SkTypeface::kUTF16_Encoding;
93 break;
94 case kUTF32_SkTextEncoding:
95 typefaceEncoding = SkTypeface::kUTF32_Encoding;
96 break;
97 default:
98 SkASSERT(kGlyphID_SkTextEncoding == encoding);
99 // we can early exit, since we already have glyphIDs
100 memcpy(glyphs, text, count << 1);
101 return count;
102 }
103
104 (void)fTypeface->charsToGlyphs(text, typefaceEncoding, glyphs, count);
105 return count;
106 }
107
measureText(const void * text,size_t byteLength,SkTextEncoding encoding) const108 SkScalar SkFont::measureText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
109 // TODO: need access to the cache
110 return -1;
111 }
112
113 ///////////////////////////////////////////////////////////////////////////////////////////////////
114
115 #include "SkPaint.h"
116
Testing_CreateFromPaint(const SkPaint & paint)117 sk_sp<SkFont> SkFont::Testing_CreateFromPaint(const SkPaint& paint) {
118 uint32_t flags = 0;
119 if (paint.isVerticalText()) {
120 flags |= kVertical_Flag;
121 }
122 if (paint.isEmbeddedBitmapText()) {
123 flags |= kEmbeddedBitmaps_Flag;
124 }
125 if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
126 flags |= kGenA8FromLCD_Flag;
127 }
128 if (paint.isFakeBoldText()) {
129 flags |= kEmbolden_Flag;
130 }
131
132 if (SkPaint::kFull_Hinting == paint.getHinting()) {
133 flags |= kEnableByteCodeHints_Flag;
134 }
135 if (paint.isAutohinted()) {
136 flags |= kEnableAutoHints_Flag;
137 }
138 if (paint.isSubpixelText() || paint.isLinearText()) {
139 // this is our default
140 } else {
141 flags |= kUseNonlinearMetrics_Flag;
142 }
143
144 MaskType maskType = SkFont::kBW_MaskType;
145 if (paint.isAntiAlias()) {
146 maskType = paint.isLCDRenderText() ? kLCD_MaskType : kA8_MaskType;
147 }
148
149 return Make(sk_ref_sp(paint.getTypeface()), paint.getTextSize(), paint.getTextScaleX(),
150 paint.getTextSkewX(), maskType, flags);
151 }
152