Make all SkGlyph fields private
All the scalers are friends, and can still access the fields, but clients of SkGlyph can no longer access them. Change-Id: Idbc26de74ceebeac37fa8fec9277ecf8b870e5e9 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/223801 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
parent
43e97165d2
commit
793818b235
@ -118,16 +118,13 @@ class SkGlyph {
|
|||||||
public:
|
public:
|
||||||
static constexpr SkFixed kSubpixelRound = SK_FixedHalf >> SkPackedGlyphID::kSubBits;
|
static constexpr SkFixed kSubpixelRound = SK_FixedHalf >> SkPackedGlyphID::kSubBits;
|
||||||
|
|
||||||
constexpr explicit SkGlyph(SkPackedGlyphID id) : fID{id} {}
|
constexpr explicit SkGlyph(SkPackedGlyphID id) : fID{id} { }
|
||||||
explicit SkGlyph(const SkGlyphPrototype& p);
|
explicit SkGlyph(const SkGlyphPrototype& p);
|
||||||
|
|
||||||
|
|
||||||
SkVector advanceVector() const { return SkVector{fAdvanceX, fAdvanceY}; }
|
SkVector advanceVector() const { return SkVector{fAdvanceX, fAdvanceY}; }
|
||||||
SkScalar advanceX() const { return fAdvanceX; }
|
SkScalar advanceX() const { return fAdvanceX; }
|
||||||
SkScalar advanceY() const { return fAdvanceY; }
|
SkScalar advanceY() const { return fAdvanceY; }
|
||||||
|
|
||||||
bool isJustAdvance() const { return MASK_FORMAT_JUST_ADVANCE == fMaskFormat; }
|
|
||||||
bool isFullMetrics() const { return MASK_FORMAT_JUST_ADVANCE != fMaskFormat; }
|
|
||||||
SkGlyphID getGlyphID() const { return fID.code(); }
|
SkGlyphID getGlyphID() const { return fID.code(); }
|
||||||
SkPackedGlyphID getPackedID() const { return fID; }
|
SkPackedGlyphID getPackedID() const { return fID; }
|
||||||
SkFixed getSubXFixed() const { return fID.getSubXFixed(); }
|
SkFixed getSubXFixed() const { return fID.getSubXFixed(); }
|
||||||
@ -220,16 +217,6 @@ public:
|
|||||||
void ensureIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
|
void ensureIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos,
|
||||||
SkScalar* array, int* count, SkArenaAlloc* alloc);
|
SkScalar* array, int* count, SkArenaAlloc* alloc);
|
||||||
|
|
||||||
void* fImage = nullptr;
|
|
||||||
|
|
||||||
// The width and height of the glyph mask.
|
|
||||||
uint16_t fWidth = 0,
|
|
||||||
fHeight = 0;
|
|
||||||
|
|
||||||
// The offset from the glyphs origin on the baseline to the top left of the glyph mask.
|
|
||||||
int16_t fTop = 0,
|
|
||||||
fLeft = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// There are two sides to an SkGlyph, the scaler side (things that create glyph data) have
|
// There are two sides to an SkGlyph, the scaler side (things that create glyph data) have
|
||||||
// access to all the fields. Scalers are assumed to maintain all the SkGlyph invariants. The
|
// access to all the fields. Scalers are assumed to maintain all the SkGlyph invariants. The
|
||||||
@ -252,8 +239,6 @@ private:
|
|||||||
|
|
||||||
static constexpr uint16_t kMaxGlyphWidth = 1u << 13u;
|
static constexpr uint16_t kMaxGlyphWidth = 1u << 13u;
|
||||||
|
|
||||||
size_t allocImage(SkArenaAlloc* alloc);
|
|
||||||
|
|
||||||
// Support horizontal and vertical skipping strike-through / underlines.
|
// Support horizontal and vertical skipping strike-through / underlines.
|
||||||
// The caller walks the linked list looking for a match. For a horizontal underline,
|
// The caller walks the linked list looking for a match. For a horizontal underline,
|
||||||
// the fBounds contains the top and bottom of the underline. The fInterval pair contains the
|
// the fBounds contains the top and bottom of the underline. The fInterval pair contains the
|
||||||
@ -271,9 +256,22 @@ private:
|
|||||||
bool fHasPath{false};
|
bool fHasPath{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
// path == nullptr indicates there is no path.
|
size_t allocImage(SkArenaAlloc* alloc);
|
||||||
|
|
||||||
|
// path == nullptr indicates that there is no path.
|
||||||
void installPath(SkArenaAlloc* alloc, const SkPath* path);
|
void installPath(SkArenaAlloc* alloc, const SkPath* path);
|
||||||
|
|
||||||
|
// The width and height of the glyph mask.
|
||||||
|
uint16_t fWidth = 0,
|
||||||
|
fHeight = 0;
|
||||||
|
|
||||||
|
// The offset from the glyphs origin on the baseline to the top left of the glyph mask.
|
||||||
|
int16_t fTop = 0,
|
||||||
|
fLeft = 0;
|
||||||
|
|
||||||
|
// fImage must remain null if the glyph is empty or if width > kMaxGlyphWidth.
|
||||||
|
void* fImage = nullptr;
|
||||||
|
|
||||||
// Path data has tricky state. If the glyph isEmpty, then fPathData should always be nullptr,
|
// Path data has tricky state. If the glyph isEmpty, then fPathData should always be nullptr,
|
||||||
// else if fPathData is not null, then a path has been requested. The fPath field of fPathData
|
// else if fPathData is not null, then a path has been requested. The fPath field of fPathData
|
||||||
// may still be null after the request meaning that there is no path for this glyph.
|
// may still be null after the request meaning that there is no path for this glyph.
|
||||||
@ -291,9 +289,7 @@ private:
|
|||||||
// Used by the DirectWrite scaler to track state.
|
// Used by the DirectWrite scaler to track state.
|
||||||
int8_t fForceBW = 0;
|
int8_t fForceBW = 0;
|
||||||
|
|
||||||
// TODO(herb) remove friend statement after SkStrike cleanup.
|
const SkPackedGlyphID fID;
|
||||||
friend class SkStrike;
|
|
||||||
SkPackedGlyphID fID;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SkGlyphPrototype {
|
struct SkGlyphPrototype {
|
||||||
|
@ -237,7 +237,7 @@ void SkStrike::forceValidate() const {
|
|||||||
size_t memoryUsed = sizeof(*this);
|
size_t memoryUsed = sizeof(*this);
|
||||||
fGlyphMap.foreach ([&memoryUsed](const SkGlyph* glyphPtr) {
|
fGlyphMap.foreach ([&memoryUsed](const SkGlyph* glyphPtr) {
|
||||||
memoryUsed += sizeof(SkGlyph);
|
memoryUsed += sizeof(SkGlyph);
|
||||||
if (glyphPtr->fImage) {
|
if (glyphPtr->setImageHasBeenCalled()) {
|
||||||
memoryUsed += glyphPtr->imageSize();
|
memoryUsed += glyphPtr->imageSize();
|
||||||
}
|
}
|
||||||
if (glyphPtr->setPathHasBeenCalled() && glyphPtr->path() != nullptr) {
|
if (glyphPtr->setPathHasBeenCalled() && glyphPtr->path() != nullptr) {
|
||||||
|
@ -1318,15 +1318,11 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_glyph_image(const SkGlyph& glyph) {
|
|
||||||
sk_bzero(glyph.fImage, glyph.rowBytes() * glyph.fHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
|
void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
|
||||||
SkAutoMutexExclusive ac(f_t_mutex());
|
SkAutoMutexExclusive ac(f_t_mutex());
|
||||||
|
|
||||||
if (this->setupSize()) {
|
if (this->setupSize()) {
|
||||||
clear_glyph_image(glyph);
|
sk_bzero(glyph.fImage, glyph.imageSize());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1334,9 +1330,9 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
|
|||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
SK_TRACEFTR(err, "SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:%d "
|
SK_TRACEFTR(err, "SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:%d "
|
||||||
"width:%d height:%d rb:%d flags:%d) failed.",
|
"width:%d height:%d rb:%d flags:%d) failed.",
|
||||||
glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowBytes(),
|
glyph.getGlyphID(), glyph.width(), glyph.height(), glyph.rowBytes(),
|
||||||
fLoadGlyphFlags);
|
fLoadGlyphFlags);
|
||||||
clear_glyph_image(glyph);
|
sk_bzero(glyph.fImage, glyph.imageSize());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,6 +941,20 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void CTPathElement(void *info, const CGPathElement *element);
|
static void CTPathElement(void *info, const CGPathElement *element);
|
||||||
|
template<bool APPLY_PREBLEND>
|
||||||
|
static void RGBToA8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes,
|
||||||
|
const SkGlyph& glyph, const uint8_t* table8);
|
||||||
|
template<bool APPLY_PREBLEND>
|
||||||
|
static uint16_t RGBToLcd16(CGRGBPixel rgb, const uint8_t* tableR,
|
||||||
|
const uint8_t* tableG,
|
||||||
|
const uint8_t* tableB);
|
||||||
|
template<bool APPLY_PREBLEND>
|
||||||
|
static void RGBToLcd16(const CGRGBPixel* SK_RESTRICT cgPixels,
|
||||||
|
size_t cgRowBytes,
|
||||||
|
const SkGlyph& glyph,
|
||||||
|
const uint8_t* tableR,
|
||||||
|
const uint8_t* tableG,
|
||||||
|
const uint8_t* tableB);
|
||||||
|
|
||||||
Offscreen fOffscreen;
|
Offscreen fOffscreen;
|
||||||
|
|
||||||
@ -1066,12 +1080,12 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
|
size_t rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
|
||||||
if (!fCG || fSize.fWidth < glyph.fWidth || fSize.fHeight < glyph.fHeight) {
|
if (!fCG || fSize.fWidth < glyph.width() || fSize.fHeight < glyph.height()) {
|
||||||
if (fSize.fWidth < glyph.fWidth) {
|
if (fSize.fWidth < glyph.width()) {
|
||||||
fSize.fWidth = RoundSize(glyph.fWidth);
|
fSize.fWidth = RoundSize(glyph.width());
|
||||||
}
|
}
|
||||||
if (fSize.fHeight < glyph.fHeight) {
|
if (fSize.fHeight < glyph.height()) {
|
||||||
fSize.fHeight = RoundSize(glyph.fHeight);
|
fSize.fHeight = RoundSize(glyph.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
|
rowBytes = fSize.fWidth * sizeof(CGRGBPixel);
|
||||||
@ -1117,11 +1131,11 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
|
|||||||
|
|
||||||
CGRGBPixel* image = (CGRGBPixel*)fImageStorage.get();
|
CGRGBPixel* image = (CGRGBPixel*)fImageStorage.get();
|
||||||
// skip rows based on the glyph's height
|
// skip rows based on the glyph's height
|
||||||
image += (fSize.fHeight - glyph.fHeight) * fSize.fWidth;
|
image += (fSize.fHeight - glyph.height()) * fSize.fWidth;
|
||||||
|
|
||||||
// Erase to white (or transparent black if it's a color glyph, to not composite against white).
|
// Erase to white (or transparent black if it's a color glyph, to not composite against white).
|
||||||
uint32_t bgColor = (!glyph.isColor()) ? 0xFFFFFFFF : 0x00000000;
|
uint32_t bgColor = (!glyph.isColor()) ? 0xFFFFFFFF : 0x00000000;
|
||||||
sk_memset_rect32(image, bgColor, glyph.fWidth, glyph.fHeight, rowBytes);
|
sk_memset_rect32(image, bgColor, glyph.width(), glyph.height(), rowBytes);
|
||||||
|
|
||||||
float subX = 0;
|
float subX = 0;
|
||||||
float subY = 0;
|
float subY = 0;
|
||||||
@ -1130,7 +1144,7 @@ CGRGBPixel* Offscreen::getCG(const SkScalerContext_Mac& context, const SkGlyph&
|
|||||||
subY = SkFixedToFloat(glyph.getSubYFixed());
|
subY = SkFixedToFloat(glyph.getSubYFixed());
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPoint point = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight - subY);
|
CGPoint point = CGPointMake(-glyph.left() + subX, glyph.top() + glyph.height() - subY);
|
||||||
// Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPositions and took
|
// Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPositions and took
|
||||||
// 'positions' which are in text space. The glyph location (in device space) must be
|
// 'positions' which are in text space. The glyph location (in device space) must be
|
||||||
// mapped into text space, so that CG can convert it back into device space.
|
// mapped into text space, so that CG can convert it back into device space.
|
||||||
@ -1271,9 +1285,10 @@ static inline uint8_t rgb_to_a8(CGRGBPixel rgb, const uint8_t* table8) {
|
|||||||
#endif
|
#endif
|
||||||
return lum;
|
return lum;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND>
|
template<bool APPLY_PREBLEND>
|
||||||
static void rgb_to_a8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes,
|
void SkScalerContext_Mac::RGBToA8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes,
|
||||||
const SkGlyph& glyph, const uint8_t* table8) {
|
const SkGlyph& glyph, const uint8_t* table8) {
|
||||||
const int width = glyph.fWidth;
|
const int width = glyph.fWidth;
|
||||||
size_t dstRB = glyph.rowBytes();
|
size_t dstRB = glyph.rowBytes();
|
||||||
uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage;
|
uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage;
|
||||||
@ -1288,9 +1303,9 @@ static void rgb_to_a8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND>
|
template<bool APPLY_PREBLEND>
|
||||||
static inline uint16_t rgb_to_lcd16(CGRGBPixel rgb, const uint8_t* tableR,
|
uint16_t SkScalerContext_Mac::RGBToLcd16(CGRGBPixel rgb, const uint8_t* tableR,
|
||||||
const uint8_t* tableG,
|
const uint8_t* tableG,
|
||||||
const uint8_t* tableB) {
|
const uint8_t* tableB) {
|
||||||
U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 16) & 0xFF), tableR);
|
U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 16) & 0xFF), tableR);
|
||||||
U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 8) & 0xFF), tableG);
|
U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 8) & 0xFF), tableG);
|
||||||
U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 0) & 0xFF), tableB);
|
U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 0) & 0xFF), tableB);
|
||||||
@ -1301,16 +1316,21 @@ static inline uint16_t rgb_to_lcd16(CGRGBPixel rgb, const uint8_t* tableR,
|
|||||||
#endif
|
#endif
|
||||||
return SkPack888ToRGB16(r, g, b);
|
return SkPack888ToRGB16(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND>
|
template<bool APPLY_PREBLEND>
|
||||||
static void rgb_to_lcd16(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes, const SkGlyph& glyph,
|
void SkScalerContext_Mac::RGBToLcd16(const CGRGBPixel* SK_RESTRICT cgPixels,
|
||||||
const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
|
size_t cgRowBytes,
|
||||||
|
const SkGlyph& glyph,
|
||||||
|
const uint8_t* tableR,
|
||||||
|
const uint8_t* tableG,
|
||||||
|
const uint8_t* tableB) {
|
||||||
const int width = glyph.fWidth;
|
const int width = glyph.fWidth;
|
||||||
size_t dstRB = glyph.rowBytes();
|
size_t dstRB = glyph.rowBytes();
|
||||||
uint16_t* SK_RESTRICT dst = (uint16_t*)glyph.fImage;
|
uint16_t* SK_RESTRICT dst = (uint16_t*)glyph.fImage;
|
||||||
|
|
||||||
for (int y = 0; y < glyph.fHeight; y++) {
|
for (int y = 0; y < glyph.fHeight; y++) {
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(cgPixels[i], tableR, tableG, tableB);
|
dst[i] = RGBToLcd16<APPLY_PREBLEND>(cgPixels[i], tableR, tableG, tableB);
|
||||||
}
|
}
|
||||||
cgPixels = SkTAddOffset<const CGRGBPixel>(cgPixels, cgRowBytes);
|
cgPixels = SkTAddOffset<const CGRGBPixel>(cgPixels, cgRowBytes);
|
||||||
dst = SkTAddOffset<uint16_t>(dst, dstRB);
|
dst = SkTAddOffset<uint16_t>(dst, dstRB);
|
||||||
@ -1370,18 +1390,18 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
|
|||||||
switch (glyph.fMaskFormat) {
|
switch (glyph.fMaskFormat) {
|
||||||
case SkMask::kLCD16_Format: {
|
case SkMask::kLCD16_Format: {
|
||||||
if (fPreBlend.isApplicable()) {
|
if (fPreBlend.isApplicable()) {
|
||||||
rgb_to_lcd16<true>(cgPixels, cgRowBytes, glyph,
|
RGBToLcd16<true>(cgPixels, cgRowBytes, glyph,
|
||||||
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
} else {
|
} else {
|
||||||
rgb_to_lcd16<false>(cgPixels, cgRowBytes, glyph,
|
RGBToLcd16<false>(cgPixels, cgRowBytes, glyph,
|
||||||
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case SkMask::kA8_Format: {
|
case SkMask::kA8_Format: {
|
||||||
if (fPreBlend.isApplicable()) {
|
if (fPreBlend.isApplicable()) {
|
||||||
rgb_to_a8<true>(cgPixels, cgRowBytes, glyph, fPreBlend.fG);
|
RGBToA8<true>(cgPixels, cgRowBytes, glyph, fPreBlend.fG);
|
||||||
} else {
|
} else {
|
||||||
rgb_to_a8<false>(cgPixels, cgRowBytes, glyph, fPreBlend.fG);
|
RGBToA8<false>(cgPixels, cgRowBytes, glyph, fPreBlend.fG);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case SkMask::kBW_Format: {
|
case SkMask::kBW_Format: {
|
||||||
|
@ -483,14 +483,14 @@ const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
|
|||||||
SkASSERT(prev != CLR_INVALID);
|
SkASSERT(prev != CLR_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fBM && (fIsBW != isBW || fWidth < glyph.fWidth || fHeight < glyph.fHeight)) {
|
if (fBM && (fIsBW != isBW || fWidth < glyph.width() || fHeight < glyph.height())) {
|
||||||
DeleteObject(fBM);
|
DeleteObject(fBM);
|
||||||
fBM = 0;
|
fBM = 0;
|
||||||
}
|
}
|
||||||
fIsBW = isBW;
|
fIsBW = isBW;
|
||||||
|
|
||||||
fWidth = SkMax32(fWidth, glyph.fWidth);
|
fWidth = SkMax32(fWidth, glyph.width());
|
||||||
fHeight = SkMax32(fHeight, glyph.fHeight);
|
fHeight = SkMax32(fHeight, glyph.height());
|
||||||
|
|
||||||
int biWidth = isBW ? alignTo32(fWidth) : fWidth;
|
int biWidth = isBW ? alignTo32(fWidth) : fWidth;
|
||||||
|
|
||||||
@ -525,8 +525,8 @@ const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
|
|||||||
memset(fBits, 0, size);
|
memset(fBits, 0, size);
|
||||||
|
|
||||||
XFORM xform = fXform;
|
XFORM xform = fXform;
|
||||||
xform.eDx = (float)-glyph.fLeft;
|
xform.eDx = (float)-glyph.left();
|
||||||
xform.eDy = (float)-glyph.fTop;
|
xform.eDy = (float)-glyph.top();
|
||||||
SetWorldTransform(fDC, &xform);
|
SetWorldTransform(fDC, &xform);
|
||||||
|
|
||||||
uint16_t glyphID = glyph.getGlyphID();
|
uint16_t glyphID = glyph.getGlyphID();
|
||||||
@ -537,7 +537,7 @@ const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
|
|||||||
}
|
}
|
||||||
*srcRBPtr = srcRB;
|
*srcRBPtr = srcRB;
|
||||||
// offset to the start of the image
|
// offset to the start of the image
|
||||||
return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB;
|
return (const char*)fBits + (fHeight - glyph.height()) * srcRB;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -565,6 +565,13 @@ protected:
|
|||||||
private:
|
private:
|
||||||
DWORD getGDIGlyphPath(SkGlyphID glyph, UINT flags,
|
DWORD getGDIGlyphPath(SkGlyphID glyph, UINT flags,
|
||||||
SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf);
|
SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf);
|
||||||
|
template<bool APPLY_PREBLEND>
|
||||||
|
static void RGBToA8(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
|
||||||
|
const SkGlyph& glyph, const uint8_t* table8);
|
||||||
|
|
||||||
|
template<bool APPLY_PREBLEND>
|
||||||
|
static void RGBToLcd16(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
|
||||||
|
const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB);
|
||||||
|
|
||||||
HDCOffscreen fOffscreen;
|
HDCOffscreen fOffscreen;
|
||||||
/** fGsA is the non-rotational part of total matrix without the text height scale.
|
/** fGsA is the non-rotational part of total matrix without the text height scale.
|
||||||
@ -816,13 +823,13 @@ void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
|
|||||||
// Bitmap FON cannot underhang, but vector FON may.
|
// Bitmap FON cannot underhang, but vector FON may.
|
||||||
// There appears no means of determining underhang of vector FON.
|
// There appears no means of determining underhang of vector FON.
|
||||||
glyph->fLeft = SkToS16(0);
|
glyph->fLeft = SkToS16(0);
|
||||||
glyph->fAdvanceX = glyph->fWidth;
|
glyph->fAdvanceX = glyph->width();
|
||||||
glyph->fAdvanceY = 0;
|
glyph->fAdvanceY = 0;
|
||||||
|
|
||||||
// Vector FON will transform nicely, but bitmap FON do not.
|
// Vector FON will transform nicely, but bitmap FON do not.
|
||||||
if (fType == SkScalerContext_GDI::kLine_Type) {
|
if (fType == SkScalerContext_GDI::kLine_Type) {
|
||||||
SkRect bounds = SkRect::MakeXYWH(glyph->fLeft, glyph->fTop,
|
SkRect bounds = SkRect::MakeXYWH(glyph->fLeft, glyph->fTop,
|
||||||
glyph->fWidth, glyph->fHeight);
|
glyph->width(), glyph->height());
|
||||||
SkMatrix m;
|
SkMatrix m;
|
||||||
m.setAll(SkFIXEDToScalar(fMat22.eM11), -SkFIXEDToScalar(fMat22.eM21), 0,
|
m.setAll(SkFIXEDToScalar(fMat22.eM11), -SkFIXEDToScalar(fMat22.eM21), 0,
|
||||||
-SkFIXEDToScalar(fMat22.eM12), SkFIXEDToScalar(fMat22.eM22), 0,
|
-SkFIXEDToScalar(fMat22.eM12), SkFIXEDToScalar(fMat22.eM22), 0,
|
||||||
@ -1049,11 +1056,11 @@ static inline uint16_t rgb_to_lcd16(SkGdiRGB rgb, const uint8_t* tableR,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND>
|
template<bool APPLY_PREBLEND>
|
||||||
static void rgb_to_a8(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
|
void SkScalerContext_GDI::RGBToA8(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
|
||||||
const SkGlyph& glyph, const uint8_t* table8) {
|
const SkGlyph& glyph, const uint8_t* table8) {
|
||||||
const size_t dstRB = glyph.rowBytes();
|
const size_t dstRB = glyph.rowBytes();
|
||||||
const int width = glyph.fWidth;
|
const int width = glyph.width();
|
||||||
uint8_t* SK_RESTRICT dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
|
uint8_t* SK_RESTRICT dst = (uint8_t*)((char*)glyph.fImage + (glyph.height() - 1) * dstRB);
|
||||||
|
|
||||||
for (int y = 0; y < glyph.fHeight; y++) {
|
for (int y = 0; y < glyph.fHeight; y++) {
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
@ -1068,11 +1075,12 @@ static void rgb_to_a8(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND>
|
template<bool APPLY_PREBLEND>
|
||||||
static void rgb_to_lcd16(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
|
void SkScalerContext_GDI::RGBToLcd16(
|
||||||
const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
|
const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
|
||||||
|
const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
|
||||||
const size_t dstRB = glyph.rowBytes();
|
const size_t dstRB = glyph.rowBytes();
|
||||||
const int width = glyph.fWidth;
|
const int width = glyph.width();
|
||||||
uint16_t* SK_RESTRICT dst = (uint16_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
|
uint16_t* SK_RESTRICT dst = (uint16_t*)((char*)glyph.fImage + (glyph.height() - 1) * dstRB);
|
||||||
|
|
||||||
for (int y = 0; y < glyph.fHeight; y++) {
|
for (int y = 0; y < glyph.fHeight; y++) {
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
@ -1116,7 +1124,7 @@ void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) {
|
|||||||
//one with this and one without.
|
//one with this and one without.
|
||||||
SkGdiRGB* addr = (SkGdiRGB*)bits;
|
SkGdiRGB* addr = (SkGdiRGB*)bits;
|
||||||
for (int y = 0; y < glyph.fHeight; ++y) {
|
for (int y = 0; y < glyph.fHeight; ++y) {
|
||||||
for (int x = 0; x < glyph.fWidth; ++x) {
|
for (int x = 0; x < glyph.width(); ++x) {
|
||||||
int r = (addr[x] >> 16) & 0xFF;
|
int r = (addr[x] >> 16) & 0xFF;
|
||||||
int g = (addr[x] >> 8) & 0xFF;
|
int g = (addr[x] >> 8) & 0xFF;
|
||||||
int b = (addr[x] >> 0) & 0xFF;
|
int b = (addr[x] >> 0) & 0xFF;
|
||||||
@ -1136,10 +1144,10 @@ void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) {
|
|||||||
dst -= dstRB;
|
dst -= dstRB;
|
||||||
}
|
}
|
||||||
#if SK_SHOW_TEXT_BLIT_COVERAGE
|
#if SK_SHOW_TEXT_BLIT_COVERAGE
|
||||||
if (glyph.fWidth > 0 && glyph.fHeight > 0) {
|
if (glyph.width() > 0 && glyph.fHeight > 0) {
|
||||||
int bitCount = glyph.fWidth & 7;
|
int bitCount = glyph.width() & 7;
|
||||||
uint8_t* first = (uint8_t*)glyph.fImage;
|
uint8_t* first = (uint8_t*)glyph.fImage;
|
||||||
uint8_t* last = (uint8_t*)((char*)glyph.fImage + glyph.fHeight * dstRB - 1);
|
uint8_t* last = (uint8_t*)((char*)glyph.fImage + glyph.height() * dstRB - 1);
|
||||||
*first |= 1 << 7;
|
*first |= 1 << 7;
|
||||||
*last |= bitCount == 0 ? 1 : 1 << (8 - bitCount);
|
*last |= bitCount == 0 ? 1 : 1 << (8 - bitCount);
|
||||||
}
|
}
|
||||||
@ -1149,19 +1157,17 @@ void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) {
|
|||||||
// ... until we have the caller tell us that explicitly
|
// ... until we have the caller tell us that explicitly
|
||||||
const SkGdiRGB* src = (const SkGdiRGB*)bits;
|
const SkGdiRGB* src = (const SkGdiRGB*)bits;
|
||||||
if (fPreBlend.isApplicable()) {
|
if (fPreBlend.isApplicable()) {
|
||||||
rgb_to_a8<true>(src, srcRB, glyph, fPreBlend.fG);
|
RGBToA8<true>(src, srcRB, glyph, fPreBlend.fG);
|
||||||
} else {
|
} else {
|
||||||
rgb_to_a8<false>(src, srcRB, glyph, fPreBlend.fG);
|
RGBToA8<false>(src, srcRB, glyph, fPreBlend.fG);
|
||||||
}
|
}
|
||||||
} else { // LCD16
|
} else { // LCD16
|
||||||
const SkGdiRGB* src = (const SkGdiRGB*)bits;
|
const SkGdiRGB* src = (const SkGdiRGB*)bits;
|
||||||
SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
|
SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
|
||||||
if (fPreBlend.isApplicable()) {
|
if (fPreBlend.isApplicable()) {
|
||||||
rgb_to_lcd16<true>(src, srcRB, glyph,
|
RGBToLcd16<true>(src, srcRB, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
|
||||||
} else {
|
} else {
|
||||||
rgb_to_lcd16<false>(src, srcRB, glyph,
|
RGBToLcd16<false>(src, srcRB, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -490,30 +490,6 @@ HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** GetAlphaTextureBounds succeeds but sometimes returns empty bounds like
|
|
||||||
* { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
|
|
||||||
* for small, but not quite zero, sized glyphs.
|
|
||||||
* Only set as non-empty if the returned bounds are non-empty.
|
|
||||||
*/
|
|
||||||
static bool glyph_check_and_set_bounds(SkGlyph* glyph, const RECT& bbox) {
|
|
||||||
if (bbox.left >= bbox.right || bbox.top >= bbox.bottom) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're trying to pack left and top into int16_t,
|
|
||||||
// and width and height into uint16_t, after outsetting by 1.
|
|
||||||
if (!SkIRect::MakeXYWH(-32767, -32767, 65535, 65535).contains(
|
|
||||||
SkIRect::MakeLTRB(bbox.left, bbox.top, bbox.right, bbox.bottom))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
glyph->fWidth = SkToU16(bbox.right - bbox.left);
|
|
||||||
glyph->fHeight = SkToU16(bbox.bottom - bbox.top);
|
|
||||||
glyph->fLeft = SkToS16(bbox.left);
|
|
||||||
glyph->fTop = SkToS16(bbox.top);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkScalerContext_DW::isColorGlyph(const SkGlyph& glyph) {
|
bool SkScalerContext_DW::isColorGlyph(const SkGlyph& glyph) {
|
||||||
SkTScopedComPtr<IDWriteColorGlyphRunEnumerator> colorLayer;
|
SkTScopedComPtr<IDWriteColorGlyphRunEnumerator> colorLayer;
|
||||||
return getColorGlyphRun(glyph, &colorLayer);
|
return getColorGlyphRun(glyph, &colorLayer);
|
||||||
@ -673,6 +649,31 @@ void SkScalerContext_DW::generatePngMetrics(SkGlyph* glyph) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
|
void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
|
||||||
|
|
||||||
|
|
||||||
|
// GetAlphaTextureBounds succeeds but sometimes returns empty bounds like
|
||||||
|
// { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
|
||||||
|
// for small, but not quite zero, sized glyphs.
|
||||||
|
// Only set as non-empty if the returned bounds are non-empty.
|
||||||
|
auto glyphCheckAndSetBounds = [](SkGlyph* glyph, const RECT& bbox) {
|
||||||
|
if (bbox.left >= bbox.right || bbox.top >= bbox.bottom) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're trying to pack left and top into int16_t,
|
||||||
|
// and width and height into uint16_t, after outsetting by 1.
|
||||||
|
if (!SkIRect::MakeXYWH(-32767, -32767, 65535, 65535).contains(
|
||||||
|
SkIRect::MakeLTRB(bbox.left, bbox.top, bbox.right, bbox.bottom))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glyph->fWidth = SkToU16(bbox.right - bbox.left);
|
||||||
|
glyph->fHeight = SkToU16(bbox.bottom - bbox.top);
|
||||||
|
glyph->fLeft = SkToS16(bbox.left);
|
||||||
|
glyph->fTop = SkToS16(bbox.top);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
glyph->fWidth = 0;
|
glyph->fWidth = 0;
|
||||||
glyph->fHeight = 0;
|
glyph->fHeight = 0;
|
||||||
glyph->fLeft = 0;
|
glyph->fLeft = 0;
|
||||||
@ -699,7 +700,7 @@ void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
|
|||||||
HRVM(this->getBoundingBox(glyph, fRenderingMode, fTextureType, &bbox),
|
HRVM(this->getBoundingBox(glyph, fRenderingMode, fTextureType, &bbox),
|
||||||
"Requested bounding box could not be determined.");
|
"Requested bounding box could not be determined.");
|
||||||
|
|
||||||
if (glyph_check_and_set_bounds(glyph, bbox)) {
|
if (glyphCheckAndSetBounds(glyph, bbox)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,7 +715,7 @@ void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
|
|||||||
DWRITE_TEXTURE_ALIASED_1x1,
|
DWRITE_TEXTURE_ALIASED_1x1,
|
||||||
&bbox),
|
&bbox),
|
||||||
"Fallback bounding box could not be determined.");
|
"Fallback bounding box could not be determined.");
|
||||||
if (glyph_check_and_set_bounds(glyph, bbox)) {
|
if (glyphCheckAndSetBounds(glyph, bbox)) {
|
||||||
glyph->fForceBW = 1;
|
glyph->fForceBW = 1;
|
||||||
glyph->fMaskFormat = SkMask::kBW_Format;
|
glyph->fMaskFormat = SkMask::kBW_Format;
|
||||||
}
|
}
|
||||||
@ -794,15 +795,15 @@ void SkScalerContext_DW::generateFontMetrics(SkFontMetrics* metrics) {
|
|||||||
|
|
||||||
#include "include/private/SkColorData.h"
|
#include "include/private/SkColorData.h"
|
||||||
|
|
||||||
static void bilevel_to_bw(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph) {
|
void SkScalerContext_DW::BilevelToBW(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph) {
|
||||||
const int width = glyph.fWidth;
|
const int width = glyph.width();
|
||||||
const size_t dstRB = (width + 7) >> 3;
|
const size_t dstRB = (width + 7) >> 3;
|
||||||
uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
|
uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
|
||||||
|
|
||||||
int byteCount = width >> 3;
|
int byteCount = width >> 3;
|
||||||
int bitCount = width & 7;
|
int bitCount = width & 7;
|
||||||
|
|
||||||
for (int y = 0; y < glyph.fHeight; ++y) {
|
for (int y = 0; y < glyph.height(); ++y) {
|
||||||
if (byteCount > 0) {
|
if (byteCount > 0) {
|
||||||
for (int i = 0; i < byteCount; ++i) {
|
for (int i = 0; i < byteCount; ++i) {
|
||||||
unsigned byte = 0;
|
unsigned byte = 0;
|
||||||
@ -833,14 +834,15 @@ static void bilevel_to_bw(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND>
|
template<bool APPLY_PREBLEND>
|
||||||
static void grayscale_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
|
void SkScalerContext_DW::GrayscaleToA8(const uint8_t* SK_RESTRICT src,
|
||||||
const uint8_t* table8) {
|
const SkGlyph& glyph,
|
||||||
|
const uint8_t* table8) {
|
||||||
const size_t dstRB = glyph.rowBytes();
|
const size_t dstRB = glyph.rowBytes();
|
||||||
const U16CPU width = glyph.fWidth;
|
const int width = glyph.width();
|
||||||
uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
|
uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
|
||||||
|
|
||||||
for (U16CPU y = 0; y < glyph.fHeight; y++) {
|
for (int y = 0; y < glyph.height(); y++) {
|
||||||
for (U16CPU i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
U8CPU a = *(src++);
|
U8CPU a = *(src++);
|
||||||
dst[i] = sk_apply_lut_if<APPLY_PREBLEND>(a, table8);
|
dst[i] = sk_apply_lut_if<APPLY_PREBLEND>(a, table8);
|
||||||
}
|
}
|
||||||
@ -849,13 +851,15 @@ static void grayscale_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND>
|
template<bool APPLY_PREBLEND>
|
||||||
static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, const uint8_t* table8) {
|
void SkScalerContext_DW::RGBToA8(const uint8_t* SK_RESTRICT src,
|
||||||
|
const SkGlyph& glyph,
|
||||||
|
const uint8_t* table8) {
|
||||||
const size_t dstRB = glyph.rowBytes();
|
const size_t dstRB = glyph.rowBytes();
|
||||||
const U16CPU width = glyph.fWidth;
|
const int width = glyph.width();
|
||||||
uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
|
uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
|
||||||
|
|
||||||
for (U16CPU y = 0; y < glyph.fHeight; y++) {
|
for (int y = 0; y < glyph.height(); y++) {
|
||||||
for (U16CPU i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
U8CPU r = *(src++);
|
U8CPU r = *(src++);
|
||||||
U8CPU g = *(src++);
|
U8CPU g = *(src++);
|
||||||
U8CPU b = *(src++);
|
U8CPU b = *(src++);
|
||||||
@ -866,14 +870,15 @@ static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<bool APPLY_PREBLEND, bool RGB>
|
template<bool APPLY_PREBLEND, bool RGB>
|
||||||
static void rgb_to_lcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
|
void SkScalerContext_DW::RGBToLcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
|
||||||
const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
|
const uint8_t* tableR, const uint8_t* tableG,
|
||||||
|
const uint8_t* tableB) {
|
||||||
const size_t dstRB = glyph.rowBytes();
|
const size_t dstRB = glyph.rowBytes();
|
||||||
const U16CPU width = glyph.fWidth;
|
const int width = glyph.width();
|
||||||
uint16_t* SK_RESTRICT dst = static_cast<uint16_t*>(glyph.fImage);
|
uint16_t* SK_RESTRICT dst = static_cast<uint16_t*>(glyph.fImage);
|
||||||
|
|
||||||
for (U16CPU y = 0; y < glyph.fHeight; y++) {
|
for (int y = 0; y < glyph.height(); y++) {
|
||||||
for (U16CPU i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
U8CPU r, g, b;
|
U8CPU r, g, b;
|
||||||
if (RGB) {
|
if (RGB) {
|
||||||
r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR);
|
r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR);
|
||||||
@ -894,7 +899,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
|
|||||||
DWRITE_RENDERING_MODE renderingMode,
|
DWRITE_RENDERING_MODE renderingMode,
|
||||||
DWRITE_TEXTURE_TYPE textureType)
|
DWRITE_TEXTURE_TYPE textureType)
|
||||||
{
|
{
|
||||||
int sizeNeeded = glyph.fWidth * glyph.fHeight;
|
int sizeNeeded = glyph.width() * glyph.height();
|
||||||
if (DWRITE_TEXTURE_CLEARTYPE_3x1 == textureType) {
|
if (DWRITE_TEXTURE_CLEARTYPE_3x1 == textureType) {
|
||||||
sizeNeeded *= 3;
|
sizeNeeded *= 3;
|
||||||
}
|
}
|
||||||
@ -959,10 +964,10 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
|
|||||||
//NOTE: this assumes that the glyph has already been measured
|
//NOTE: this assumes that the glyph has already been measured
|
||||||
//with an exact same glyph run analysis.
|
//with an exact same glyph run analysis.
|
||||||
RECT bbox;
|
RECT bbox;
|
||||||
bbox.left = glyph.fLeft;
|
bbox.left = glyph.left();
|
||||||
bbox.top = glyph.fTop;
|
bbox.top = glyph.top();
|
||||||
bbox.right = glyph.fLeft + glyph.fWidth;
|
bbox.right = glyph.left() + glyph.width();
|
||||||
bbox.bottom = glyph.fTop + glyph.fHeight;
|
bbox.bottom = glyph.top() + glyph.height();
|
||||||
{
|
{
|
||||||
Shared l(DWriteFactoryMutex);
|
Shared l(DWriteFactoryMutex);
|
||||||
HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
|
HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
|
||||||
@ -986,14 +991,14 @@ void SkScalerContext_DW::generateColorGlyphImage(const SkGlyph& glyph) {
|
|||||||
SkASSERT(colorLayers.get());
|
SkASSERT(colorLayers.get());
|
||||||
|
|
||||||
SkMatrix matrix = fSkXform;
|
SkMatrix matrix = fSkXform;
|
||||||
matrix.postTranslate(-SkIntToScalar(glyph.fLeft), -SkIntToScalar(glyph.fTop));
|
matrix.postTranslate(-SkIntToScalar(glyph.left()), -SkIntToScalar(glyph.top()));
|
||||||
if (this->isSubpixel()) {
|
if (this->isSubpixel()) {
|
||||||
matrix.postTranslate(SkFixedToScalar(glyph.getSubXFixed()),
|
matrix.postTranslate(SkFixedToScalar(glyph.getSubXFixed()),
|
||||||
SkFixedToScalar(glyph.getSubYFixed()));
|
SkFixedToScalar(glyph.getSubYFixed()));
|
||||||
}
|
}
|
||||||
SkRasterClip rc(SkIRect::MakeWH(glyph.fWidth, glyph.fHeight));
|
SkRasterClip rc(SkIRect::MakeWH(glyph.width(), glyph.height()));
|
||||||
SkDraw draw;
|
SkDraw draw;
|
||||||
draw.fDst = SkPixmap(SkImageInfo::MakeN32(glyph.fWidth, glyph.fHeight, kPremul_SkAlphaType),
|
draw.fDst = SkPixmap(SkImageInfo::MakeN32(glyph.width(), glyph.height(), kPremul_SkAlphaType),
|
||||||
glyph.fImage,
|
glyph.fImage,
|
||||||
glyph.rowBytesUsingFormat(SkMask::Format::kARGB32_Format));
|
glyph.rowBytesUsingFormat(SkMask::Format::kARGB32_Format));
|
||||||
draw.fMatrix = &matrix;
|
draw.fMatrix = &matrix;
|
||||||
@ -1066,7 +1071,7 @@ void SkScalerContext_DW::generatePngGlyphImage(const SkGlyph& glyph) {
|
|||||||
sk_sp<SkImage> image = SkImage::MakeFromEncoded(std::move(data));
|
sk_sp<SkImage> image = SkImage::MakeFromEncoded(std::move(data));
|
||||||
|
|
||||||
SkBitmap dstBitmap;
|
SkBitmap dstBitmap;
|
||||||
dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight,
|
dstBitmap.setInfo(SkImageInfo::Make(glyph.width(), glyph.height(),
|
||||||
kN32_SkColorType,
|
kN32_SkColorType,
|
||||||
kPremul_SkAlphaType),
|
kPremul_SkAlphaType),
|
||||||
glyph.rowBytes());
|
glyph.rowBytes());
|
||||||
@ -1074,7 +1079,7 @@ void SkScalerContext_DW::generatePngGlyphImage(const SkGlyph& glyph) {
|
|||||||
|
|
||||||
SkCanvas canvas(dstBitmap);
|
SkCanvas canvas(dstBitmap);
|
||||||
canvas.clear(SK_ColorTRANSPARENT);
|
canvas.clear(SK_ColorTRANSPARENT);
|
||||||
canvas.translate(-glyph.fLeft, -glyph.fTop);
|
canvas.translate(-glyph.left(), -glyph.top());
|
||||||
if (this->isSubpixel()) {
|
if (this->isSubpixel()) {
|
||||||
canvas.translate(SkFixedToScalar(glyph.getSubXFixed()),
|
canvas.translate(SkFixedToScalar(glyph.getSubXFixed()),
|
||||||
SkFixedToScalar(glyph.getSubYFixed()));
|
SkFixedToScalar(glyph.getSubYFixed()));
|
||||||
@ -1120,34 +1125,34 @@ void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
|
|||||||
if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) {
|
if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) {
|
||||||
SkASSERT(SkMask::kBW_Format == glyph.fMaskFormat);
|
SkASSERT(SkMask::kBW_Format == glyph.fMaskFormat);
|
||||||
SkASSERT(DWRITE_TEXTURE_ALIASED_1x1 == textureType);
|
SkASSERT(DWRITE_TEXTURE_ALIASED_1x1 == textureType);
|
||||||
bilevel_to_bw(src, glyph);
|
BilevelToBW(src, glyph);
|
||||||
} else if (!isLCD(fRec)) {
|
} else if (!isLCD(fRec)) {
|
||||||
if (textureType == DWRITE_TEXTURE_ALIASED_1x1) {
|
if (textureType == DWRITE_TEXTURE_ALIASED_1x1) {
|
||||||
if (fPreBlend.isApplicable()) {
|
if (fPreBlend.isApplicable()) {
|
||||||
grayscale_to_a8<true>(src, glyph, fPreBlend.fG);
|
GrayscaleToA8<true>(src, glyph, fPreBlend.fG);
|
||||||
} else {
|
} else {
|
||||||
grayscale_to_a8<false>(src, glyph, fPreBlend.fG);
|
GrayscaleToA8<false>(src, glyph, fPreBlend.fG);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fPreBlend.isApplicable()) {
|
if (fPreBlend.isApplicable()) {
|
||||||
rgb_to_a8<true>(src, glyph, fPreBlend.fG);
|
RGBToA8<true>(src, glyph, fPreBlend.fG);
|
||||||
} else {
|
} else {
|
||||||
rgb_to_a8<false>(src, glyph, fPreBlend.fG);
|
RGBToA8<false>(src, glyph, fPreBlend.fG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
|
SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat);
|
||||||
if (fPreBlend.isApplicable()) {
|
if (fPreBlend.isApplicable()) {
|
||||||
if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) {
|
if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) {
|
||||||
rgb_to_lcd16<true, false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
RGBToLcd16<true, false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
} else {
|
} else {
|
||||||
rgb_to_lcd16<true, true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
RGBToLcd16<true, true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) {
|
if (fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag) {
|
||||||
rgb_to_lcd16<false, false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
RGBToLcd16<false, false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
} else {
|
} else {
|
||||||
rgb_to_lcd16<false, true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
RGBToLcd16<false, true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,22 @@ protected:
|
|||||||
void generateFontMetrics(SkFontMetrics*) override;
|
void generateFontMetrics(SkFontMetrics*) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void BilevelToBW(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph);
|
||||||
|
|
||||||
|
template<bool APPLY_PREBLEND>
|
||||||
|
static void GrayscaleToA8(const uint8_t* SK_RESTRICT src,
|
||||||
|
const SkGlyph& glyph,
|
||||||
|
const uint8_t* table8);
|
||||||
|
|
||||||
|
template<bool APPLY_PREBLEND>
|
||||||
|
static void RGBToA8(const uint8_t* SK_RESTRICT src,
|
||||||
|
const SkGlyph& glyph,
|
||||||
|
const uint8_t* table8);
|
||||||
|
|
||||||
|
template<bool APPLY_PREBLEND, bool RGB>
|
||||||
|
static void RGBToLcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
|
||||||
|
const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB);
|
||||||
|
|
||||||
const void* drawDWMask(const SkGlyph& glyph,
|
const void* drawDWMask(const SkGlyph& glyph,
|
||||||
DWRITE_RENDERING_MODE renderingMode,
|
DWRITE_RENDERING_MODE renderingMode,
|
||||||
DWRITE_TEXTURE_TYPE textureType);
|
DWRITE_TEXTURE_TYPE textureType);
|
||||||
|
Loading…
Reference in New Issue
Block a user