1 /* 2 * Copyright 2010 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 #ifndef GrGlyph_DEFINED 9 #define GrGlyph_DEFINED 10 11 #include "include/gpu/GrTypes.h" 12 #include "src/gpu/GrDrawOpAtlas.h" 13 #include "src/gpu/geometry/GrRect.h" 14 15 #include "include/core/SkPath.h" 16 #include "include/private/SkChecksum.h" 17 #include "include/private/SkFixed.h" 18 19 struct GrGlyph { 20 enum MaskStyle { 21 kCoverage_MaskStyle, 22 kDistance_MaskStyle 23 }; 24 FormatFromSkGlyphGrGlyph25 static GrMaskFormat FormatFromSkGlyph(SkMask::Format format) { 26 switch (format) { 27 case SkMask::kBW_Format: 28 case SkMask::kSDF_Format: 29 // fall through to kA8 -- we store BW and SDF glyphs in our 8-bit cache 30 case SkMask::kA8_Format: 31 return kA8_GrMaskFormat; 32 case SkMask::k3D_Format: 33 return kA8_GrMaskFormat; // ignore the mul and add planes, just use the mask 34 case SkMask::kLCD16_Format: 35 return kA565_GrMaskFormat; 36 case SkMask::kARGB32_Format: 37 return kARGB_GrMaskFormat; 38 default: 39 SkDEBUGFAIL("unsupported SkMask::Format"); 40 return kA8_GrMaskFormat; 41 } 42 } 43 MaskStyleFromSkGlyphGrGlyph44 static MaskStyle MaskStyleFromSkGlyph(const SkGlyph& skGlyph) { 45 return skGlyph.maskFormat() == SkMask::kSDF_Format 46 ? GrGlyph::MaskStyle::kDistance_MaskStyle 47 : GrGlyph::MaskStyle::kCoverage_MaskStyle; 48 } 49 GrGlyphGrGlyph50 GrGlyph(const SkGlyph& skGlyph) 51 : fPackedID{skGlyph.getPackedID()} 52 , fMaskFormat{FormatFromSkGlyph(skGlyph.maskFormat())} 53 , fMaskStyle{MaskStyleFromSkGlyph(skGlyph)} 54 , fBounds{GrIRect16::Make(skGlyph.iRect())} {} 55 56 destRectGrGlyph57 SkRect destRect(SkPoint origin) { 58 return SkRect::MakeXYWH( 59 SkIntToScalar(fBounds.fLeft) + origin.x(), 60 SkIntToScalar(fBounds.fTop) + origin.y(), 61 SkIntToScalar(fBounds.width()), 62 SkIntToScalar(fBounds.height())); 63 } 64 destRectGrGlyph65 SkRect destRect(SkPoint origin, SkScalar textScale) { 66 if (fMaskStyle == kCoverage_MaskStyle) { 67 return SkRect::MakeXYWH( 68 SkIntToScalar(fBounds.fLeft) * textScale + origin.x(), 69 SkIntToScalar(fBounds.fTop) * textScale + origin.y(), 70 SkIntToScalar(fBounds.width()) * textScale, 71 SkIntToScalar(fBounds.height()) * textScale); 72 } else { 73 return SkRect::MakeXYWH( 74 (SkIntToScalar(fBounds.fLeft) + SK_DistanceFieldInset) * textScale + origin.x(), 75 (SkIntToScalar(fBounds.fTop) + SK_DistanceFieldInset) * textScale + origin.y(), 76 (SkIntToScalar(fBounds.width()) - 2 * SK_DistanceFieldInset) * textScale, 77 (SkIntToScalar(fBounds.height()) - 2 * SK_DistanceFieldInset) * textScale); 78 } 79 } 80 widthGrGlyph81 int width() const { return fBounds.width(); } heightGrGlyph82 int height() const { return fBounds.height(); } pageIndexGrGlyph83 uint32_t pageIndex() const { return GrDrawOpAtlas::GetPageIndexFromID(fID); } maskStyleGrGlyph84 MaskStyle maskStyle() const { return fMaskStyle; } 85 86 // GetKey and Hash for the the hash table. GetKeyGrGlyph87 static const SkPackedGlyphID& GetKey(const GrGlyph& glyph) { 88 return glyph.fPackedID; 89 } 90 HashGrGlyph91 static uint32_t Hash(SkPackedGlyphID key) { 92 return SkChecksum::Mix(key.hash()); 93 } 94 95 const SkPackedGlyphID fPackedID; 96 const GrMaskFormat fMaskFormat; 97 const MaskStyle fMaskStyle; 98 const GrIRect16 fBounds; 99 SkIPoint16 fAtlasLocation{0, 0}; 100 GrDrawOpAtlas::AtlasID fID{GrDrawOpAtlas::kInvalidAtlasID}; 101 }; 102 103 #endif 104