本文整理汇总了C++中SkMatrix::getScaleX方法的典型用法代码示例。如果您正苦于以下问题:C++ SkMatrix::getScaleX方法的具体用法?C++ SkMatrix::getScaleX怎么用?C++ SkMatrix::getScaleX使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkMatrix
的用法示例。
在下文中一共展示了SkMatrix::getScaleX方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SkScalerContext
SkScalerContext_Ascender::SkScalerContext_Ascender(const SkDescriptor* desc)
: SkScalerContext(desc)
{
int size = aca_Get_FontHandleRec_Size();
fHandle = (aca_FontHandle)sk_malloc_throw(size);
// get the pointer to the font
fFontStream = new SkMMAPStream("/UcsGB2312-Hei-H.FDL");
fHintStream = new SkMMAPStream("/genv6-23.bin");
void* hints = sk_malloc_throw(fHintStream->getLength());
memcpy(hints, fHintStream->getMemoryBase(), fHintStream->getLength());
aca_Create_Font_Handle(fHandle,
(void*)fFontStream->getMemoryBase(), fFontStream->getLength(),
"fred",
hints, fHintStream->getLength());
// compute our factors from the record
SkMatrix m;
fRec.getSingleMatrix(&m);
// now compute our scale factors
SkScalar sx = m.getScaleX();
SkScalar sy = m.getScaleY();
int ppemX = SkScalarRound(sx);
int ppemY = SkScalarRound(sy);
size = aca_Find_Font_Memory_Required(fHandle, ppemX, ppemY);
size *= 8; // Jeff suggests this :)
fWorkspace = sk_malloc_throw(size);
aca_Set_Font_Memory(fHandle, (uint8_t*)fWorkspace, size);
aca_GlyphAttribsRec rec;
memset(&rec, 0, sizeof(rec));
rec.xSize = ppemX;
rec.ySize = ppemY;
rec.doAdjust = true;
rec.doExceptions = true;
rec.doGlyphHints = true;
rec.doInterpolate = true;
rec.grayMode = 2;
aca_Set_Font_Attributes(fHandle, &rec, &size);
fGlyphWorkspace = sk_malloc_throw(size);
aca_Set_Glyph_Memory(fHandle, fGlyphWorkspace);
}
示例2: nextafterf
SkLinearBitmapPipeline::SkLinearBitmapPipeline(
const SkMatrix& inverse,
SkFilterQuality filterQuality,
SkShader::TileMode xTile, SkShader::TileMode yTile,
float postAlpha,
const SkPixmap& srcPixmap)
{
SkISize dimensions = srcPixmap.info().dimensions();
const SkImageInfo& srcImageInfo = srcPixmap.info();
SkMatrix adjustedInverse = inverse;
if (filterQuality == kNone_SkFilterQuality) {
if (inverse.getScaleX() >= 0.0f) {
adjustedInverse.setTranslateX(
nextafterf(inverse.getTranslateX(), std::floor(inverse.getTranslateX())));
}
if (inverse.getScaleY() >= 0.0f) {
adjustedInverse.setTranslateY(
nextafterf(inverse.getTranslateY(), std::floor(inverse.getTranslateY())));
}
}
SkScalar dx = adjustedInverse.getScaleX();
// If it is an index 8 color type, the sampler converts to unpremul for better fidelity.
SkAlphaType alphaType = srcImageInfo.alphaType();
if (srcPixmap.colorType() == kIndex_8_SkColorType) {
alphaType = kUnpremul_SkAlphaType;
}
// As the stages are built, the chooser function may skip a stage. For example, with the
// identity matrix, the matrix stage is skipped, and the tilerStage is the first stage.
auto placementStage = choose_pixel_placer(alphaType, postAlpha, &fPixelStage);
auto samplerStage = choose_pixel_sampler(placementStage,
filterQuality, srcPixmap, &fSampleStage);
auto tilerStage = choose_tiler(samplerStage,
dimensions, xTile, yTile, filterQuality, dx, &fTiler);
fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage);
}
示例3: mapDstScaleTranslate
void SkLatticeIter::mapDstScaleTranslate(const SkMatrix& matrix) {
SkASSERT(matrix.isScaleTranslate());
SkScalar tx = matrix.getTranslateX();
SkScalar sx = matrix.getScaleX();
for (int i = 0; i < fDstX.count(); i++) {
fDstX[i] = fDstX[i] * sx + tx;
}
SkScalar ty = matrix.getTranslateY();
SkScalar sy = matrix.getScaleY();
for (int i = 0; i < fDstY.count(); i++) {
fDstY[i] = fDstY[i] * sy + ty;
}
}
示例4: SkASSERT
GrCCPathCache::MaskTransform::MaskTransform(const SkMatrix& m, SkIVector* shift)
: fMatrix2x2{m.getScaleX(), m.getSkewX(), m.getSkewY(), m.getScaleY()} {
SkASSERT(!m.hasPerspective());
Sk2f translate = Sk2f(m.getTranslateX(), m.getTranslateY());
Sk2f transFloor;
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
// On Android framework we pre-round view matrix translates to integers for better caching.
transFloor = translate;
#else
transFloor = translate.floor();
(translate - transFloor).store(fSubpixelTranslate);
#endif
shift->set((int)transFloor[0], (int)transFloor[1]);
SkASSERT((float)shift->fX == transFloor[0]); // Make sure transFloor had integer values.
SkASSERT((float)shift->fY == transFloor[1]);
}
示例5: calculate_translation
static void calculate_translation(bool applyVM,
const SkMatrix& newViewMatrix, SkScalar newX, SkScalar newY,
const SkMatrix& currentViewMatrix, SkScalar currentX,
SkScalar currentY, SkScalar* transX, SkScalar* transY) {
if (applyVM) {
*transX = newViewMatrix.getTranslateX() +
newViewMatrix.getScaleX() * (newX - currentX) +
newViewMatrix.getSkewX() * (newY - currentY) -
currentViewMatrix.getTranslateX();
*transY = newViewMatrix.getTranslateY() +
newViewMatrix.getSkewY() * (newX - currentX) +
newViewMatrix.getScaleY() * (newY - currentY) -
currentViewMatrix.getTranslateY();
} else {
*transX = newX - currentX;
*transY = newY - currentY;
}
}
示例6: dump
void SkFlatMatrix::dump() const {
const SkMatrix* matrix = (const SkMatrix*) fMatrixData;
char pBuffer[DUMP_BUFFER_SIZE];
char* bufferPtr = pBuffer;
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"matrix: ");
SkScalar scaleX = matrix->getScaleX();
SkMatrix defaultMatrix;
defaultMatrix.reset();
if (scaleX != defaultMatrix.getScaleX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"scaleX:%g ", SkScalarToFloat(scaleX));
SkScalar scaleY = matrix->getScaleY();
if (scaleY != defaultMatrix.getScaleY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"scaleY:%g ", SkScalarToFloat(scaleY));
SkScalar skewX = matrix->getSkewX();
if (skewX != defaultMatrix.getSkewX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"skewX:%g ", SkScalarToFloat(skewX));
SkScalar skewY = matrix->getSkewY();
if (skewY != defaultMatrix.getSkewY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"skewY:%g ", SkScalarToFloat(skewY));
SkScalar translateX = matrix->getTranslateX();
if (translateX != defaultMatrix.getTranslateX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"translateX:%g ", SkScalarToFloat(translateX));
SkScalar translateY = matrix->getTranslateY();
if (translateY != defaultMatrix.getTranslateY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"translateY:%g ", SkScalarToFloat(translateY));
SkScalar perspX = matrix->getPerspX();
if (perspX != defaultMatrix.getPerspX())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"perspX:%g ", SkFractToFloat(perspX));
SkScalar perspY = matrix->getPerspY();
if (perspY != defaultMatrix.getPerspY())
bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
"perspY:%g ", SkFractToFloat(perspY));
SkDebugf("%s\n", pBuffer);
}
示例7: push_concat
bool SkDeferredCanvas::push_concat(const SkMatrix& mat) {
if (mat.getType() > (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
return false;
}
// At the moment, we don't know which ops can scale and which can also flip, so
// we reject negative scales for now
if (mat.getScaleX() < 0 || mat.getScaleY() < 0) {
return false;
}
int index = fRecs.count() - 1;
SkMatrix m;
if (index >= 0 && fRecs[index].isConcat(&m)) {
m.preConcat(mat);
fRecs[index].setConcat(m);
} else {
fRecs.append()->setConcat(mat);
}
return true;
}
示例8: didConcat
void SkDumpCanvas::didConcat(const SkMatrix& matrix) {
SkString str;
switch (matrix.getType()) {
case SkMatrix::kTranslate_Mask:
this->dump(kMatrix_Verb, nullptr, "translate(%g %g)",
SkScalarToFloat(matrix.getTranslateX()),
SkScalarToFloat(matrix.getTranslateY()));
break;
case SkMatrix::kScale_Mask:
this->dump(kMatrix_Verb, nullptr, "scale(%g %g)",
SkScalarToFloat(matrix.getScaleX()),
SkScalarToFloat(matrix.getScaleY()));
break;
default:
matrix.toString(&str);
this->dump(kMatrix_Verb, nullptr, "concat(%s)", str.c_str());
break;
}
this->INHERITED::didConcat(matrix);
}
示例9: didConcat
void LoggingCanvas::didConcat(const SkMatrix& matrix)
{
AutoLogger logger(this);
RefPtr<JSONObject> params;
switch (matrix.getType()) {
case SkMatrix::kTranslate_Mask:
params = logger.logItemWithParams("translate");
params->setNumber("dx", matrix.getTranslateX());
params->setNumber("dy", matrix.getTranslateY());
break;
case SkMatrix::kScale_Mask:
params = logger.logItemWithParams("scale");
params->setNumber("scaleX", matrix.getScaleX());
params->setNumber("scaleY", matrix.getScaleY());
break;
default:
params = logger.logItemWithParams("concat");
params->setArray("matrix", arrayForSkMatrix(matrix));
}
this->SkCanvas::didConcat(matrix);
}
示例10: mustRegenerate
bool GrAtlasTextBlob::mustRegenerate(const SkPaint& paint,
GrColor color, const SkMaskFilter::BlurRec& blurRec,
const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
// If we have LCD text then our canonical color will be set to transparent, in this case we have
// to regenerate the blob on any color change
// We use the grPaint to get any color filter effects
if (fKey.fCanonicalColor == SK_ColorTRANSPARENT &&
fPaintColor != color) {
return true;
}
if (fInitialViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) {
return true;
}
if (fInitialViewMatrix.hasPerspective() && !fInitialViewMatrix.cheapEqualTo(viewMatrix)) {
return true;
}
// We only cache one masked version
if (fKey.fHasBlur &&
(fBlurRec.fSigma != blurRec.fSigma ||
fBlurRec.fStyle != blurRec.fStyle ||
fBlurRec.fQuality != blurRec.fQuality)) {
return true;
}
// Similarly, we only cache one version for each style
if (fKey.fStyle != SkPaint::kFill_Style &&
(fStrokeInfo.fFrameWidth != paint.getStrokeWidth() ||
fStrokeInfo.fMiterLimit != paint.getStrokeMiter() ||
fStrokeInfo.fJoin != paint.getStrokeJoin())) {
return true;
}
// Mixed blobs must be regenerated. We could probably figure out a way to do integer scrolls
// for mixed blobs if this becomes an issue.
if (this->hasBitmap() && this->hasDistanceField()) {
// Identical viewmatrices and we can reuse in all cases
if (fInitialViewMatrix.cheapEqualTo(viewMatrix) && x == fInitialX && y == fInitialY) {
return false;
}
return true;
}
if (this->hasBitmap()) {
if (fInitialViewMatrix.getScaleX() != viewMatrix.getScaleX() ||
fInitialViewMatrix.getScaleY() != viewMatrix.getScaleY() ||
fInitialViewMatrix.getSkewX() != viewMatrix.getSkewX() ||
fInitialViewMatrix.getSkewY() != viewMatrix.getSkewY()) {
return true;
}
// We can update the positions in the cachedtextblobs without regenerating the whole blob,
// but only for integer translations.
// This cool bit of math will determine the necessary translation to apply to the already
// generated vertex coordinates to move them to the correct position
SkScalar transX = viewMatrix.getTranslateX() +
viewMatrix.getScaleX() * (x - fInitialX) +
viewMatrix.getSkewX() * (y - fInitialY) -
fInitialViewMatrix.getTranslateX();
SkScalar transY = viewMatrix.getTranslateY() +
viewMatrix.getSkewY() * (x - fInitialX) +
viewMatrix.getScaleY() * (y - fInitialY) -
fInitialViewMatrix.getTranslateY();
if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY)) {
return true;
}
} else if (this->hasDistanceField()) {
// A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would result in a different
// distance field being generated, so we have to regenerate in those cases
SkScalar newMaxScale = viewMatrix.getMaxScale();
SkScalar oldMaxScale = fInitialViewMatrix.getMaxScale();
SkScalar scaleAdjust = newMaxScale / oldMaxScale;
if (scaleAdjust < fMaxMinScale || scaleAdjust > fMinMaxScale) {
return true;
}
}
// It is possible that a blob has neither distanceField nor bitmaptext. This is in the case
// when all of the runs inside the blob are drawn as paths. In this case, we always regenerate
// the blob anyways at flush time, so no need to regenerate explicitly
return false;
}
示例11: computeMatrices
void SkScalerContextRec::computeMatrices(PreMatrixScale preMatrixScale, SkVector* s, SkMatrix* sA,
SkMatrix* GsA, SkMatrix* G_inv, SkMatrix* A_out)
{
// A is the 'total' matrix.
SkMatrix A;
this->getSingleMatrix(&A);
// The caller may find the 'total' matrix useful when dealing directly with EM sizes.
if (A_out) {
*A_out = A;
}
// If the 'total' matrix is singular, set the 'scale' to something finite and zero the matrices.
// All underlying ports have issues with zero text size, so use the matricies to zero.
// Map the vectors [0,1], [1,0], [1,1] and [1,-1] (the EM) through the 'total' matrix.
// If the length of one of these vectors is less than 1/256 then an EM filling square will
// never affect any pixels.
SkVector diag[4] = { { A.getScaleX() , A.getSkewY() },
{ A.getSkewX(), A.getScaleY() },
{ A.getScaleX() + A.getSkewX(), A.getScaleY() + A.getSkewY() },
{ A.getScaleX() - A.getSkewX(), A.getScaleY() - A.getSkewY() }, };
if (diag[0].lengthSqd() <= SK_ScalarNearlyZero * SK_ScalarNearlyZero ||
diag[1].lengthSqd() <= SK_ScalarNearlyZero * SK_ScalarNearlyZero ||
diag[2].lengthSqd() <= SK_ScalarNearlyZero * SK_ScalarNearlyZero ||
diag[3].lengthSqd() <= SK_ScalarNearlyZero * SK_ScalarNearlyZero)
{
s->fX = SK_Scalar1;
s->fY = SK_Scalar1;
sA->setScale(0, 0);
if (GsA) {
GsA->setScale(0, 0);
}
if (G_inv) {
G_inv->reset();
}
return;
}
// GA is the matrix A with rotation removed.
SkMatrix GA;
bool skewedOrFlipped = A.getSkewX() || A.getSkewY() || A.getScaleX() < 0 || A.getScaleY() < 0;
if (skewedOrFlipped) {
// h is where A maps the horizontal baseline.
SkPoint h = SkPoint::Make(SK_Scalar1, 0);
A.mapPoints(&h, 1);
// G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
SkMatrix G;
SkComputeGivensRotation(h, &G);
GA = G;
GA.preConcat(A);
// The 'remainingRotation' is G inverse, which is fairly simple since G is 2x2 rotational.
if (G_inv) {
G_inv->setAll(
G.get(SkMatrix::kMScaleX), -G.get(SkMatrix::kMSkewX), G.get(SkMatrix::kMTransX),
-G.get(SkMatrix::kMSkewY), G.get(SkMatrix::kMScaleY), G.get(SkMatrix::kMTransY),
G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(SkMatrix::kMPersp2));
}
} else {
GA = A;
if (G_inv) {
G_inv->reset();
}
}
// At this point, given GA, create s.
switch (preMatrixScale) {
case kFull_PreMatrixScale:
s->fX = SkScalarAbs(GA.get(SkMatrix::kMScaleX));
s->fY = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
break;
case kVertical_PreMatrixScale: {
SkScalar yScale = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
s->fX = yScale;
s->fY = yScale;
break;
}
case kVerticalInteger_PreMatrixScale: {
SkScalar realYScale = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
SkScalar intYScale = SkScalarRoundToScalar(realYScale);
if (intYScale == 0) {
intYScale = SK_Scalar1;
}
s->fX = intYScale;
s->fY = intYScale;
break;
}
}
// The 'remaining' matrix sA is the total matrix A without the scale.
if (!skewedOrFlipped && (
(kFull_PreMatrixScale == preMatrixScale) ||
(kVertical_PreMatrixScale == preMatrixScale && A.getScaleX() == A.getScaleY())))
{
// If GA == A and kFull_PreMatrixScale, sA is identity.
// If GA == A and kVertical_PreMatrixScale and A.scaleX == A.scaleY, sA is identity.
sA->reset();
//.........这里部分代码省略.........
示例12: setProperty
bool SkDrawMatrix::setProperty(int index, SkScriptValue& scriptValue) {
SkScalar number = scriptValue.fOperand.fScalar;
switch (index) {
case SK_PROPERTY(translate):
// SkScalar xy[2];
SkASSERT(scriptValue.fType == SkType_Array);
SkASSERT(scriptValue.fOperand.fArray->getType() == SkType_Float);
SkASSERT(scriptValue.fOperand.fArray->count() == 2);
// SkParse::FindScalars(scriptValue.fOperand.fString->c_str(), xy, 2);
fMatrix.setTranslateX((*scriptValue.fOperand.fArray)[0].fScalar);
fMatrix.setTranslateY((*scriptValue.fOperand.fArray)[1].fScalar);
return true;
case SK_PROPERTY(perspectX):
#ifdef SK_SCALAR_IS_FIXED
fMatrix.setPerspX(SkFixedToFract(number));
#else
fMatrix.setPerspX(number);
#endif
break;
case SK_PROPERTY(perspectY):
#ifdef SK_SCALAR_IS_FIXED
fMatrix.setPerspY(SkFixedToFract(number));
#else
fMatrix.setPerspY(number);
#endif
break;
case SK_PROPERTY(rotate): {
SkMatrix temp;
temp.setRotate(number, 0, 0);
fMatrix.setScaleX(temp.getScaleX());
fMatrix.setScaleY(temp.getScaleY());
fMatrix.setSkewX(temp.getSkewX());
fMatrix.setSkewY(temp.getSkewY());
} break;
case SK_PROPERTY(scale):
fMatrix.setScaleX(number);
fMatrix.setScaleY(number);
break;
case SK_PROPERTY(scaleX):
fMatrix.setScaleX(number);
break;
case SK_PROPERTY(scaleY):
fMatrix.setScaleY(number);
break;
case SK_PROPERTY(skewX):
fMatrix.setSkewX(number);
break;
case SK_PROPERTY(skewY):
fMatrix.setSkewY(number);
break;
case SK_PROPERTY(translateX):
fMatrix.setTranslateX(number);
break;
case SK_PROPERTY(translateY):
fMatrix.setTranslateY(number);
break;
default:
SkASSERT(0);
return false;
}
fConcat = fMatrix;
return true;
}
示例13: ac
SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
: SkScalerContext(desc), fFTSize(NULL) {
SkAutoMutexAcquire ac(gFTMutex);
FT_Error err;
if (gFTCount == 0) {
err = FT_Init_FreeType(&gFTLibrary);
// SkDEBUGF(("FT_Init_FreeType returned %d\n", err));
SkASSERT(err == 0);
}
++gFTCount;
// load the font file
fFaceRec = ref_ft_face(fRec.fFontID);
fFace = fFaceRec ? fFaceRec->fFace : NULL;
// compute our factors from the record
SkMatrix m;
fRec.getSingleMatrix(&m);
#ifdef DUMP_STRIKE_CREATION
SkString keyString;
SkFontHost::GetDescriptorKeyString(desc, &keyString);
printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize),
SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX),
SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0][1]),
SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1][1]),
fRec.fHints, fRec.fMaskFormat, keyString.c_str());
#endif
// now compute our scale factors
SkScalar sx = m.getScaleX();
SkScalar sy = m.getScaleY();
if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) {
// sort of give up on hinting
sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX()));
sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy));
sx = sy = SkScalarAve(sx, sy);
SkScalar inv = SkScalarInvert(sx);
// flip the skew elements to go from our Y-down system to FreeType's
fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv));
fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv));
fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv));
fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv));
} else {
fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
fMatrix22.xy = fMatrix22.yx = 0;
}
fScaleX = SkScalarToFixed(sx);
fScaleY = SkScalarToFixed(sy);
// compute the flags we send to Load_Glyph
{
uint32_t flags = FT_LOAD_DEFAULT;
uint32_t render_flags = FT_LOAD_TARGET_NORMAL;
// we force autohinting at the moment
switch (fRec.fHints) {
case kNo_Hints:
flags |= FT_LOAD_NO_HINTING;
break;
case kSubpixel_Hints:
flags |= FT_LOAD_FORCE_AUTOHINT;
render_flags = FT_LOAD_TARGET_LIGHT;
break;
case kNormal_Hints:
flags |= FT_LOAD_FORCE_AUTOHINT;
#ifdef ANDROID
/* Switch to light hinting (vertical only) to address some chars
that behaved poorly with NORMAL. In the future we could consider
making this choice exposed at runtime to the caller.
*/
render_flags = FT_LOAD_TARGET_LIGHT;
#endif
break;
}
if (SkMask::kBW_Format == fRec.fMaskFormat)
render_flags = FT_LOAD_TARGET_MONO;
else if (SkMask::kLCD_Format == fRec.fMaskFormat)
render_flags = FT_LOAD_TARGET_LCD;
fLoadGlyphFlags = flags | render_flags;
}
// now create the FT_Size
{
FT_Error err;
err = FT_New_Size(fFace, &fFTSize);
if (err != 0) {
//.........这里部分代码省略.........
示例14: switch
SkScalerContext_CairoFT::SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc)
: SkScalerContext_FreeType_Base(typeface, desc)
{
SkMatrix matrix;
fRec.getSingleMatrix(&matrix);
cairo_font_face_t* fontFace = static_cast<SkCairoFTTypeface*>(typeface)->getFontFace();
cairo_matrix_t fontMatrix, ctMatrix;
cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0);
cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0);
// We need to ensure that the font options match for hinting, as generateMetrics()
// uses the fScaledFont which uses these font options
cairo_font_options_t *fontOptions = cairo_font_options_create();
FT_Int32 loadFlags = FT_LOAD_DEFAULT;
if (SkMask::kBW_Format == fRec.fMaskFormat) {
// See http://code.google.com/p/chromium/issues/detail?id=43252#c24
loadFlags = FT_LOAD_TARGET_MONO;
if (fRec.getHinting() == SkPaint::kNo_Hinting) {
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
loadFlags = FT_LOAD_NO_HINTING;
}
} else {
switch (fRec.getHinting()) {
case SkPaint::kNo_Hinting:
loadFlags = FT_LOAD_NO_HINTING;
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
break;
case SkPaint::kSlight_Hinting:
loadFlags = FT_LOAD_TARGET_LIGHT; // This implies FORCE_AUTOHINT
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
break;
case SkPaint::kNormal_Hinting:
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM);
if (fRec.fFlags & SkScalerContext::kForceAutohinting_Flag) {
loadFlags = FT_LOAD_FORCE_AUTOHINT;
}
break;
case SkPaint::kFull_Hinting:
cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
if (fRec.fFlags & SkScalerContext::kForceAutohinting_Flag) {
loadFlags = FT_LOAD_FORCE_AUTOHINT;
}
if (isLCD(fRec)) {
if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) {
loadFlags = FT_LOAD_TARGET_LCD_V;
} else {
loadFlags = FT_LOAD_TARGET_LCD;
}
}
break;
default:
SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
break;
}
}
fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions);
cairo_font_options_destroy(fontOptions);
if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
loadFlags |= FT_LOAD_NO_BITMAP;
}
// Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
// advances, as fontconfig and cairo do.
// See http://code.google.com/p/skia/issues/detail?id=222.
loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
#ifdef FT_LOAD_COLOR
loadFlags |= FT_LOAD_COLOR;
#endif
fLoadGlyphFlags = loadFlags;
}
示例15: drawPattern
void NativeImageSkia::drawPattern(
GraphicsContext* context,
const FloatRect& floatSrcRect,
const FloatSize& scale,
const FloatPoint& phase,
CompositeOperator compositeOp,
const FloatRect& destRect,
blink::WebBlendMode blendMode,
const IntSize& repeatSpacing) const
{
FloatRect normSrcRect = floatSrcRect;
normSrcRect.intersect(FloatRect(0, 0, bitmap().width(), bitmap().height()));
if (destRect.isEmpty() || normSrcRect.isEmpty())
return; // nothing to draw
SkMatrix totalMatrix = context->getTotalMatrix();
SkScalar ctmScaleX = totalMatrix.getScaleX();
SkScalar ctmScaleY = totalMatrix.getScaleY();
totalMatrix.preScale(scale.width(), scale.height());
// Figure out what size the bitmap will be in the destination. The
// destination rect is the bounds of the pattern, we need to use the
// matrix to see how big it will be.
SkRect destRectTarget;
totalMatrix.mapRect(&destRectTarget, normSrcRect);
float destBitmapWidth = SkScalarToFloat(destRectTarget.width());
float destBitmapHeight = SkScalarToFloat(destRectTarget.height());
// Compute the resampling mode.
ResamplingMode resampling;
if (context->isAccelerated() || context->printing())
resampling = LinearResampling;
else
resampling = computeResamplingMode(totalMatrix, normSrcRect.width(), normSrcRect.height(), destBitmapWidth, destBitmapHeight);
resampling = limitResamplingMode(context, resampling);
SkMatrix shaderTransform;
RefPtr<SkShader> shader;
bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap());
// Bicubic filter is only applied to defer-decoded images, see
// NativeImageSkia::draw for details.
bool useBicubicFilter = resampling == AwesomeResampling && isLazyDecoded;
if (resampling == AwesomeResampling && !useBicubicFilter) {
// Do nice resampling.
float scaleX = destBitmapWidth / normSrcRect.width();
float scaleY = destBitmapHeight / normSrcRect.height();
SkRect scaledSrcRect;
// The image fragment generated here is not exactly what is
// requested. The scale factor used is approximated and image
// fragment is slightly larger to align to integer
// boundaries.
SkBitmap resampled = extractScaledImageFragment(normSrcRect, scaleX, scaleY, &scaledSrcRect);
if (repeatSpacing.isZero()) {
shader = adoptRef(SkShader::CreateBitmapShader(resampled, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
} else {
shader = adoptRef(SkShader::CreateBitmapShader(
createBitmapWithSpace(resampled, repeatSpacing.width() * ctmScaleX, repeatSpacing.height() * ctmScaleY),
SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
}
// Since we just resized the bitmap, we need to remove the scale
// applied to the pixels in the bitmap shader. This means we need
// CTM * shaderTransform to have identity scale. Since we
// can't modify CTM (or the rectangle will be drawn in the wrong
// place), we must set shaderTransform's scale to the inverse of
// CTM scale.
shaderTransform.setScale(ctmScaleX ? 1 / ctmScaleX : 1, ctmScaleY ? 1 / ctmScaleY : 1);
} else {
// No need to resample before drawing.
SkBitmap srcSubset;
bitmap().extractSubset(&srcSubset, enclosingIntRect(normSrcRect));
if (repeatSpacing.isZero()) {
shader = adoptRef(SkShader::CreateBitmapShader(srcSubset, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
} else {
shader = adoptRef(SkShader::CreateBitmapShader(
createBitmapWithSpace(srcSubset, repeatSpacing.width() * ctmScaleX, repeatSpacing.height() * ctmScaleY),
SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode));
}
// Because no resizing occurred, the shader transform should be
// set to the pattern's transform, which just includes scale.
shaderTransform.setScale(scale.width(), scale.height());
}
// We also need to translate it such that the origin of the pattern is the
// origin of the destination rect, which is what WebKit expects. Skia uses
// the coordinate system origin as the base for the pattern. If WebKit wants
// a shifted image, it will shift it from there using the shaderTransform.
float adjustedX = phase.x() + normSrcRect.x() * scale.width();
float adjustedY = phase.y() + normSrcRect.y() * scale.height();
shaderTransform.postTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjustedY));
shader->setLocalMatrix(shaderTransform);
SkPaint paint;
paint.setShader(shader.get());
paint.setXfermode(WebCoreCompositeToSkiaComposite(compositeOp, blendMode).get());
//.........这里部分代码省略.........