/*
|
* Copyright 2010 Google Inc.
|
*
|
* Use of this source code is governed by a BSD-style license that can be
|
* found in the LICENSE file.
|
*/
|
|
#ifndef GrGlyph_DEFINED
|
#define GrGlyph_DEFINED
|
|
#include "GrDrawOpAtlas.h"
|
#include "GrRect.h"
|
#include "GrTypes.h"
|
|
#include "SkChecksum.h"
|
#include "SkFixed.h"
|
#include "SkPath.h"
|
|
struct GrGlyph {
|
enum MaskStyle {
|
kCoverage_MaskStyle,
|
kDistance_MaskStyle
|
};
|
|
static GrMaskFormat FormatFromSkGlyph(const SkGlyph& glyph) {
|
SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
|
switch (format) {
|
case SkMask::kBW_Format:
|
case SkMask::kSDF_Format:
|
// fall through to kA8 -- we store BW and SDF glyphs in our 8-bit cache
|
case SkMask::kA8_Format:
|
return kA8_GrMaskFormat;
|
case SkMask::k3D_Format:
|
return kA8_GrMaskFormat; // ignore the mul and add planes, just use the mask
|
case SkMask::kLCD16_Format:
|
return kA565_GrMaskFormat;
|
case SkMask::kARGB32_Format:
|
return kARGB_GrMaskFormat;
|
default:
|
SkDEBUGFAIL("unsupported SkMask::Format");
|
return kA8_GrMaskFormat;
|
}
|
}
|
|
static GrIRect16 BoundsFromSkGlyph(const SkGlyph& glyph) {
|
return GrIRect16::MakeXYWH(glyph.fLeft,
|
glyph.fTop,
|
glyph.fWidth,
|
glyph.fHeight);
|
}
|
|
static MaskStyle MaskStyleFromSkGlyph(const SkGlyph& skGlyph) {
|
return (SkMask::Format)skGlyph.fMaskFormat == SkMask::kSDF_Format
|
? GrGlyph::MaskStyle::kDistance_MaskStyle
|
: GrGlyph::MaskStyle::kCoverage_MaskStyle;
|
}
|
|
GrGlyph(const SkGlyph& skGlyph)
|
: fPackedID{skGlyph.getPackedID()}
|
, fMaskFormat{FormatFromSkGlyph(skGlyph)}
|
, fMaskStyle{MaskStyleFromSkGlyph(skGlyph)}
|
, fBounds{BoundsFromSkGlyph(skGlyph)} {}
|
|
|
SkRect destRect(SkPoint origin) {
|
return SkRect::MakeXYWH(
|
SkIntToScalar(fBounds.fLeft) + origin.x(),
|
SkIntToScalar(fBounds.fTop) + origin.y(),
|
SkIntToScalar(fBounds.width()),
|
SkIntToScalar(fBounds.height()));
|
}
|
|
SkRect destRect(SkPoint origin, SkScalar textScale) {
|
if (fMaskStyle == kCoverage_MaskStyle) {
|
return SkRect::MakeXYWH(
|
SkIntToScalar(fBounds.fLeft) * textScale + origin.x(),
|
SkIntToScalar(fBounds.fTop) * textScale + origin.y(),
|
SkIntToScalar(fBounds.width()) * textScale,
|
SkIntToScalar(fBounds.height()) * textScale);
|
} else {
|
return SkRect::MakeXYWH(
|
(SkIntToScalar(fBounds.fLeft) + SK_DistanceFieldInset) * textScale + origin.x(),
|
(SkIntToScalar(fBounds.fTop) + SK_DistanceFieldInset) * textScale + origin.y(),
|
(SkIntToScalar(fBounds.width()) - 2 * SK_DistanceFieldInset) * textScale,
|
(SkIntToScalar(fBounds.height()) - 2 * SK_DistanceFieldInset) * textScale);
|
}
|
}
|
|
int width() const { return fBounds.width(); }
|
int height() const { return fBounds.height(); }
|
uint32_t pageIndex() const { return GrDrawOpAtlas::GetPageIndexFromID(fID); }
|
MaskStyle maskStyle() const { return fMaskStyle; }
|
|
// GetKey and Hash for the the hash table.
|
static const SkPackedGlyphID& GetKey(const GrGlyph& glyph) {
|
return glyph.fPackedID;
|
}
|
|
static uint32_t Hash(SkPackedGlyphID key) {
|
return SkChecksum::Mix(key.hash());
|
}
|
|
const SkPackedGlyphID fPackedID;
|
const GrMaskFormat fMaskFormat;
|
const MaskStyle fMaskStyle;
|
const GrIRect16 fBounds;
|
SkIPoint16 fAtlasLocation{0, 0};
|
GrDrawOpAtlas::AtlasID fID{GrDrawOpAtlas::kInvalidAtlasID};
|
};
|
|
#endif
|