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