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