本文整理汇总了C++中SkMatrix::get方法的典型用法代码示例。如果您正苦于以下问题:C++ SkMatrix::get方法的具体用法?C++ SkMatrix::get怎么用?C++ SkMatrix::get使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkMatrix
的用法示例。
在下文中一共展示了SkMatrix::get方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: concatCTM
void GraphicsContext::concatCTM(const SkMatrix& affine)
{
if (paintingDisabled())
return;
if (!affine.isIdentity())
nvgTransform(platformContext()->canvas(), affine.get(SkMatrix::kMScaleX),
affine.get(SkMatrix::kMSkewY), affine.get(SkMatrix::kMSkewX),
affine.get(SkMatrix::kMScaleY), affine.get(SkMatrix::kMTransX),
affine.get(SkMatrix::kMTransY));
//platformContext()->canvas()->concat(affine);
}
示例2: SkASSERT
static inline bool get_direction(const SkPath& path, const SkMatrix& m, SkPath::Direction* dir) {
if (!path.cheapComputeDirection(dir)) {
return false;
}
// check whether m reverses the orientation
SkASSERT(!m.hasPerspective());
SkScalar det2x2 = SkScalarMul(m.get(SkMatrix::kMScaleX), m.get(SkMatrix::kMScaleY)) -
SkScalarMul(m.get(SkMatrix::kMSkewX), m.get(SkMatrix::kMSkewY));
if (det2x2 < 0) {
*dir = SkPath::OppositeDirection(*dir);
}
return true;
}
示例3: setup_MC_state
static void setup_MC_state(SkMCState* state, const SkMatrix& matrix, const SkRegion& clip) {
// initialize the struct
state->clipRectCount = 0;
// capture the matrix
for (int i = 0; i < 9; i++) {
state->matrix[i] = matrix.get(i);
}
/*
* capture the clip
*
* storage is allocated on the stack for the first 4 rects. This value was
* chosen somewhat arbitrarily, but does allow us to represent simple clips
* and some more common complex clips (e.g. a clipRect with a sub-rect
* clipped out of its interior) without needing to malloc any additional memory.
*/
SkSWriter32<4*sizeof(ClipRect)> clipWriter;
if (!clip.isEmpty()) {
// only returns the b/w clip so aa clips fail
SkRegion::Iterator clip_iterator(clip);
for (; !clip_iterator.done(); clip_iterator.next()) {
// this assumes the SkIRect is stored in l,t,r,b ordering which
// matches the ordering of our ClipRect struct
clipWriter.writeIRect(clip_iterator.rect());
state->clipRectCount++;
}
}
// allocate memory for the clip then and copy them to the struct
state->clipRects = (ClipRect*) sk_malloc_throw(clipWriter.bytesWritten());
clipWriter.flatten(state->clipRects);
}
示例4: didConcat
void SkJSONCanvas::didConcat(const SkMatrix& matrix) {
Json::Value command(Json::objectValue);
switch (matrix.getType()) {
case SkMatrix::kTranslate_Mask:
command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TRANSLATE);
command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(matrix.get(SkMatrix::kMTransX));
command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(matrix.get(SkMatrix::kMTransY));
break;
case SkMatrix::kScale_Mask:
command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SCALE);
command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(matrix.get(SkMatrix::kMScaleX));
command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(matrix.get(SkMatrix::kMScaleY));
break;
default:
this->didSetMatrix(this->getTotalMatrix());
return;
}
fCommands.append(command);
}
示例5: are_equal
static bool are_equal(skiatest::Reporter* reporter,
const SkMatrix& a,
const SkMatrix& b) {
bool equal = a == b;
bool cheapEqual = a.cheapEqualTo(b);
if (equal != cheapEqual) {
#ifdef SK_SCALAR_IS_FLOAT
if (equal) {
bool foundZeroSignDiff = false;
for (int i = 0; i < 9; ++i) {
float aVal = a.get(i);
float bVal = b.get(i);
int aValI = *SkTCast<int*>(&aVal);
int bValI = *SkTCast<int*>(&bVal);
if (0 == aVal && 0 == bVal && aValI != bValI) {
foundZeroSignDiff = true;
} else {
REPORTER_ASSERT(reporter, aVal == bVal && aValI == aValI);
}
}
REPORTER_ASSERT(reporter, foundZeroSignDiff);
} else {
bool foundNaN = false;
for (int i = 0; i < 9; ++i) {
float aVal = a.get(i);
float bVal = b.get(i);
int aValI = *SkTCast<int*>(&aVal);
int bValI = *SkTCast<int*>(&bVal);
if (sk_float_isnan(aVal) && aValI == bValI) {
foundNaN = true;
} else {
REPORTER_ASSERT(reporter, aVal == bVal && aValI == bValI);
}
}
REPORTER_ASSERT(reporter, foundNaN);
}
#else
REPORTER_ASSERT(reporter, false);
#endif
}
return equal;
}
示例6: getValues
static void getValues(JNIEnv* env, jobject clazz, jlong matrixHandle, jfloatArray values) {
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
AutoJavaFloatArray autoValues(env, values, 9, kRW_JNIAccess);
float* dst = autoValues.ptr();
#ifdef SK_SCALAR_IS_FLOAT
for (int i = 0; i < 9; i++) {
dst[i] = matrix->get(i);
}
#else
SkASSERT(false);
#endif
}
示例7: setSnapshotTransform
static void setSnapshotTransform(sp<SurfaceControl>& surfaceControl, SkMatrix &matrix, float alpha) {
if (surfaceControl != NULL) {
#ifdef SK_SCALAR_IS_FIXED
for (int i = 0; i < 6; i++) {
tmpFloats[i] = SkFixedToFloat(matrix.get(i));
}
for (int j = 6; j < 9; j++) {
tmpFloats[j] = SkFractToFloat(matrix.get(j));
}
#else
for (int i = 0; i < 9; i++) {
tmpFloats[i] = matrix.get(i);
}
#endif
surfaceControl->setPosition(tmpFloats[MTRANS_X], tmpFloats[MTRANS_Y]);
surfaceControl->setMatrix(tmpFloats[MSCALE_X], tmpFloats[MSKEW_Y],
tmpFloats[MSKEW_X], tmpFloats[MSCALE_Y]);
// LOGD("(trans_x,trans_y,scale_x,scale_y)=(%f,%f,%f,%f)",
// tmpFloats[MSCALE_X], tmpFloats[MSKEW_Y],
// tmpFloats[MSKEW_X], tmpFloats[MSCALE_Y]);
surfaceControl->setAlpha(alpha);
}
}
示例8: setSkMatrix
void GrGLSLProgramDataManager::setSkMatrix(UniformHandle u, const SkMatrix& matrix) const {
float mt[] = {
matrix.get(SkMatrix::kMScaleX),
matrix.get(SkMatrix::kMSkewY),
matrix.get(SkMatrix::kMPersp0),
matrix.get(SkMatrix::kMSkewX),
matrix.get(SkMatrix::kMScaleY),
matrix.get(SkMatrix::kMPersp1),
matrix.get(SkMatrix::kMTransX),
matrix.get(SkMatrix::kMTransY),
matrix.get(SkMatrix::kMPersp2),
};
this->setMatrix3f(u, mt);
}
示例9: NativeGetValues
void Matrix::NativeGetValues(
/* [in] */ Int64 matrixHandle,
/* [out] */ ArrayOf<Float>* values)
{
SkASSERT(values->GetLength() >= 9);
SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
// AutoJavaFloatArray autoValues(env, values, 9, kRW_JNIAccess);
float* dst = values->GetPayload();
#ifdef SK_SCALAR_IS_FLOAT
for (int i = 0; i < 9; i++) {
dst[i] = matrix->get(i);
}
#else
SkASSERT(FALSE);
#endif
}
示例10: android_view_MotionEvent_nativeTransform
static void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
jint nativePtr, jobject matrixObj) {
SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
float m[9];
m[0] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleX));
m[1] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewX));
m[2] = SkScalarToFloat(matrix->get(SkMatrix::kMTransX));
m[3] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewY));
m[4] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleY));
m[5] = SkScalarToFloat(matrix->get(SkMatrix::kMTransY));
m[6] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp0));
m[7] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp1));
m[8] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp2));
event->transform(m);
}
示例11: SkScalerContext
SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
const SkScalerContextEffects& effects,
const SkDescriptor* desc)
: SkScalerContext(typeface, effects, desc)
, fTypeface(SkRef(typeface))
, fGlyphCount(-1) {
#if SK_HAS_DWRITE_2_H
fTypeface->fFactory->QueryInterface<IDWriteFactory2>(&fFactory2);
SkTScopedComPtr<IDWriteFontFace2> fontFace2;
fTypeface->fDWriteFontFace->QueryInterface<IDWriteFontFace2>(&fontFace2);
fIsColorFont = fFactory2.get() && fontFace2.get() && fontFace2->IsColorFont();
#endif
// In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC
// except when bi-level rendering is requested or there are embedded
// bi-level bitmaps (and the embedded bitmap flag is set and no rotation).
//
// DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do
// this. As a result, determine the actual size of the text and then see if
// there are any embedded bi-level bitmaps of that size. If there are, then
// force bitmaps by requesting bi-level rendering.
//
// FreeType allows for separate ppemX and ppemY, but DirectWrite assumes
// square pixels and only uses ppemY. Therefore the transform must track any
// non-uniform x-scale.
//
// Also, rotated glyphs should have the same absolute advance widths as
// horizontal glyphs and the subpixel flag should not affect glyph shapes.
SkVector scale;
SkMatrix GsA;
fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale,
&scale, &fSkXform, &GsA, &fG_inv);
fXform.m11 = SkScalarToFloat(fSkXform.getScaleX());
fXform.m12 = SkScalarToFloat(fSkXform.getSkewY());
fXform.m21 = SkScalarToFloat(fSkXform.getSkewX());
fXform.m22 = SkScalarToFloat(fSkXform.getScaleY());
fXform.dx = 0;
fXform.dy = 0;
fGsA.m11 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleX));
fGsA.m12 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewY)); // This should be ~0.
fGsA.m21 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewX));
fGsA.m22 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleY));
fGsA.dx = 0;
fGsA.dy = 0;
// realTextSize is the actual device size we want (as opposed to the size the user requested).
// gdiTextSize is the size we request when GDI compatible.
// If the scale is negative, this means the matrix will do the flip anyway.
const SkScalar realTextSize = scale.fY;
// Due to floating point math, the lower bits are suspect. Round carefully.
SkScalar gdiTextSize = SkScalarRoundToScalar(realTextSize * 64.0f) / 64.0f;
if (gdiTextSize == 0) {
gdiTextSize = SK_Scalar1;
}
bool bitmapRequested = SkToBool(fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag);
bool treatLikeBitmap = false;
bool axisAlignedBitmap = false;
if (bitmapRequested) {
// When embedded bitmaps are requested, treat the entire range like
// a bitmap strike if the range is gridfit only and contains a bitmap.
int bitmapPPEM = SkScalarTruncToInt(gdiTextSize);
PPEMRange range = { bitmapPPEM, bitmapPPEM };
expand_range_if_gridfit_only(typeface, bitmapPPEM, &range);
treatLikeBitmap = has_bitmap_strike(typeface, range);
axisAlignedBitmap = is_axis_aligned(fRec);
}
// If the user requested aliased, do so with aliased compatible metrics.
if (SkMask::kBW_Format == fRec.fMaskFormat) {
fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_ALIASED;
fTextureType = DWRITE_TEXTURE_ALIASED_1x1;
fTextSizeMeasure = gdiTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
// If we can use a bitmap, use gdi classic rendering and measurement.
// This will not always provide a bitmap, but matches expected behavior.
} else if (treatLikeBitmap && axisAlignedBitmap) {
fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
fTextSizeMeasure = gdiTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
// If rotated but the horizontal text could have used a bitmap,
// render high quality rotated glyphs but measure using bitmap metrics.
} else if (treatLikeBitmap) {
fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
fTextSizeMeasure = gdiTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
//.........这里部分代码省略.........
示例12: GA
SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
const SkDescriptor* desc)
: SkScalerContext(typeface, desc)
, fTypeface(SkRef(typeface))
, fGlyphCount(-1) {
// In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC
// except when bi-level rendering is requested or there are embedded
// bi-level bitmaps (and the embedded bitmap flag is set and no rotation).
//
// DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do
// this. As a result, determine the actual size of the text and then see if
// there are any embedded bi-level bitmaps of that size. If there are, then
// force bitmaps by requesting bi-level rendering.
//
// FreeType allows for separate ppemX and ppemY, but DirectWrite assumes
// square pixels and only uses ppemY. Therefore the transform must track any
// non-uniform x-scale.
//
// Also, rotated glyphs should have the same absolute advance widths as
// horizontal glyphs and the subpixel flag should not affect glyph shapes.
// A is the total matrix.
SkMatrix A;
fRec.getSingleMatrix(&A);
// 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 is the matrix A with rotation removed.
SkMatrix GA(G);
GA.preConcat(A);
// realTextSize is the actual device size we want (as opposed to the size the user requested).
// gdiTextSize is the size we request when GDI compatible.
// If the scale is negative, this means the matrix will do the flip anyway.
SkScalar realTextSize = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
// Due to floating point math, the lower bits are suspect. Round carefully.
SkScalar gdiTextSize = SkScalarRoundToScalar(realTextSize * 64.0f) / 64.0f;
if (gdiTextSize == 0) {
gdiTextSize = SK_Scalar1;
}
bool bitmapRequested = SkToBool(fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag);
bool treatLikeBitmap = false;
bool axisAlignedBitmap = false;
if (bitmapRequested) {
// When embedded bitmaps are requested, treat the entire range like
// a bitmap strike if the range is gridfit only and contains a bitmap.
int bitmapPPEM = SkScalarTruncToInt(gdiTextSize);
PPEMRange range = { bitmapPPEM, bitmapPPEM };
expand_range_if_gridfit_only(typeface, bitmapPPEM, &range);
treatLikeBitmap = has_bitmap_strike(typeface, range);
axisAlignedBitmap = is_axis_aligned(fRec);
}
// If the user requested aliased, do so with aliased compatible metrics.
if (SkMask::kBW_Format == fRec.fMaskFormat) {
fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_ALIASED;
fTextureType = DWRITE_TEXTURE_ALIASED_1x1;
fTextSizeMeasure = gdiTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
// If we can use a bitmap, use gdi classic rendering and measurement.
// This will not always provide a bitmap, but matches expected behavior.
} else if (treatLikeBitmap && axisAlignedBitmap) {
fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
fTextSizeMeasure = gdiTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
// If rotated but the horizontal text could have used a bitmap,
// render high quality rotated glyphs but measure using bitmap metrics.
} else if (treatLikeBitmap) {
fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
fTextSizeMeasure = gdiTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
// Fonts that have hints but no gasp table get non-symmetric rendering.
// Usually such fonts have low quality hints which were never tested
// with anything but GDI ClearType classic. Such fonts often rely on
// drop out control in the y direction in order to be legible.
} else if (is_hinted_without_gasp(typeface)) {
fTextSizeRender = gdiTextSize;
fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
fTextSizeMeasure = realTextSize;
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
// The normal case is to use natural symmetric rendering and linear metrics.
//.........这里部分代码省略.........
示例13: 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();
//.........这里部分代码省略.........
示例14: SkScalarNearlyZero
void GrPathUtils::QuadUVMatrix::set(const SkPoint qPts[3]) {
SkMatrix m;
// We want M such that M * xy_pt = uv_pt
// We know M * control_pts = [0 1/2 1]
// [0 0 1]
// [1 1 1]
// And control_pts = [x0 x1 x2]
// [y0 y1 y2]
// [1 1 1 ]
// We invert the control pt matrix and post concat to both sides to get M.
// Using the known form of the control point matrix and the result, we can
// optimize and improve precision.
double x0 = qPts[0].fX;
double y0 = qPts[0].fY;
double x1 = qPts[1].fX;
double y1 = qPts[1].fY;
double x2 = qPts[2].fX;
double y2 = qPts[2].fY;
double det = x0*y1 - y0*x1 + x2*y0 - y2*x0 + x1*y2 - y1*x2;
if (!sk_float_isfinite(det)
|| SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero)) {
// The quad is degenerate. Hopefully this is rare. Find the pts that are
// farthest apart to compute a line (unless it is really a pt).
SkScalar maxD = qPts[0].distanceToSqd(qPts[1]);
int maxEdge = 0;
SkScalar d = qPts[1].distanceToSqd(qPts[2]);
if (d > maxD) {
maxD = d;
maxEdge = 1;
}
d = qPts[2].distanceToSqd(qPts[0]);
if (d > maxD) {
maxD = d;
maxEdge = 2;
}
// We could have a tolerance here, not sure if it would improve anything
if (maxD > 0) {
// Set the matrix to give (u = 0, v = distance_to_line)
SkVector lineVec = qPts[(maxEdge + 1)%3] - qPts[maxEdge];
// when looking from the point 0 down the line we want positive
// distances to be to the left. This matches the non-degenerate
// case.
lineVec.setOrthog(lineVec, SkPoint::kLeft_Side);
// first row
fM[0] = 0;
fM[1] = 0;
fM[2] = 0;
// second row
fM[3] = lineVec.fX;
fM[4] = lineVec.fY;
fM[5] = -lineVec.dot(qPts[maxEdge]);
} else {
// It's a point. It should cover zero area. Just set the matrix such
// that (u, v) will always be far away from the quad.
fM[0] = 0; fM[1] = 0; fM[2] = 100.f;
fM[3] = 0; fM[4] = 0; fM[5] = 100.f;
}
} else {
double scale = 1.0/det;
// compute adjugate matrix
double a2, a3, a4, a5, a6, a7, a8;
a2 = x1*y2-x2*y1;
a3 = y2-y0;
a4 = x0-x2;
a5 = x2*y0-x0*y2;
a6 = y0-y1;
a7 = x1-x0;
a8 = x0*y1-x1*y0;
// this performs the uv_pts*adjugate(control_pts) multiply,
// then does the scale by 1/det afterwards to improve precision
m[SkMatrix::kMScaleX] = (float)((0.5*a3 + a6)*scale);
m[SkMatrix::kMSkewX] = (float)((0.5*a4 + a7)*scale);
m[SkMatrix::kMTransX] = (float)((0.5*a5 + a8)*scale);
m[SkMatrix::kMSkewY] = (float)(a6*scale);
m[SkMatrix::kMScaleY] = (float)(a7*scale);
m[SkMatrix::kMTransY] = (float)(a8*scale);
// kMPersp0 & kMPersp1 should algebraically be zero
m[SkMatrix::kMPersp0] = 0.0f;
m[SkMatrix::kMPersp1] = 0.0f;
m[SkMatrix::kMPersp2] = (float)((a2 + a5 + a8)*scale);
// It may not be normalized to have 1.0 in the bottom right
float m33 = m.get(SkMatrix::kMPersp2);
if (1.f != m33) {
m33 = 1.f / m33;
fM[0] = m33 * m.get(SkMatrix::kMScaleX);
fM[1] = m33 * m.get(SkMatrix::kMSkewX);
fM[2] = m33 * m.get(SkMatrix::kMTransX);
fM[3] = m33 * m.get(SkMatrix::kMSkewY);
fM[4] = m33 * m.get(SkMatrix::kMScaleY);
fM[5] = m33 * m.get(SkMatrix::kMTransY);
} else {
//.........这里部分代码省略.........
示例15: GrCrash
void GrPathUtils::QuadUVMatrix::set(const GrPoint qPts[3]) {
// can't make this static, no cons :(
SkMatrix UVpts;
#ifndef SK_SCALAR_IS_FLOAT
GrCrash("Expected scalar is float.");
#endif
SkMatrix m;
// We want M such that M * xy_pt = uv_pt
// We know M * control_pts = [0 1/2 1]
// [0 0 1]
// [1 1 1]
// We invert the control pt matrix and post concat to both sides to get M.
UVpts.setAll(0, SK_ScalarHalf, SK_Scalar1,
0, 0, SK_Scalar1,
SkScalarToPersp(SK_Scalar1),
SkScalarToPersp(SK_Scalar1),
SkScalarToPersp(SK_Scalar1));
m.setAll(qPts[0].fX, qPts[1].fX, qPts[2].fX,
qPts[0].fY, qPts[1].fY, qPts[2].fY,
SkScalarToPersp(SK_Scalar1),
SkScalarToPersp(SK_Scalar1),
SkScalarToPersp(SK_Scalar1));
if (!m.invert(&m)) {
// The quad is degenerate. Hopefully this is rare. Find the pts that are
// farthest apart to compute a line (unless it is really a pt).
SkScalar maxD = qPts[0].distanceToSqd(qPts[1]);
int maxEdge = 0;
SkScalar d = qPts[1].distanceToSqd(qPts[2]);
if (d > maxD) {
maxD = d;
maxEdge = 1;
}
d = qPts[2].distanceToSqd(qPts[0]);
if (d > maxD) {
maxD = d;
maxEdge = 2;
}
// We could have a tolerance here, not sure if it would improve anything
if (maxD > 0) {
// Set the matrix to give (u = 0, v = distance_to_line)
GrVec lineVec = qPts[(maxEdge + 1)%3] - qPts[maxEdge];
// when looking from the point 0 down the line we want positive
// distances to be to the left. This matches the non-degenerate
// case.
lineVec.setOrthog(lineVec, GrPoint::kLeft_Side);
lineVec.dot(qPts[0]);
// first row
fM[0] = 0;
fM[1] = 0;
fM[2] = 0;
// second row
fM[3] = lineVec.fX;
fM[4] = lineVec.fY;
fM[5] = -lineVec.dot(qPts[maxEdge]);
} else {
// It's a point. It should cover zero area. Just set the matrix such
// that (u, v) will always be far away from the quad.
fM[0] = 0; fM[1] = 0; fM[2] = 100.f;
fM[3] = 0; fM[4] = 0; fM[5] = 100.f;
}
} else {
m.postConcat(UVpts);
// The matrix should not have perspective.
SkDEBUGCODE(static const SkScalar gTOL = SkFloatToScalar(1.f / 100.f));
GrAssert(SkScalarAbs(m.get(SkMatrix::kMPersp0)) < gTOL);
GrAssert(SkScalarAbs(m.get(SkMatrix::kMPersp1)) < gTOL);
// It may not be normalized to have 1.0 in the bottom right
float m33 = m.get(SkMatrix::kMPersp2);
if (1.f != m33) {
m33 = 1.f / m33;
fM[0] = m33 * m.get(SkMatrix::kMScaleX);
fM[1] = m33 * m.get(SkMatrix::kMSkewX);
fM[2] = m33 * m.get(SkMatrix::kMTransX);
fM[3] = m33 * m.get(SkMatrix::kMSkewY);
fM[4] = m33 * m.get(SkMatrix::kMScaleY);
fM[5] = m33 * m.get(SkMatrix::kMTransY);
} else {
fM[0] = m.get(SkMatrix::kMScaleX);
fM[1] = m.get(SkMatrix::kMSkewX);
fM[2] = m.get(SkMatrix::kMTransX);
fM[3] = m.get(SkMatrix::kMSkewY);
fM[4] = m.get(SkMatrix::kMScaleY);
fM[5] = m.get(SkMatrix::kMTransY);
}
}
}
开发者ID:IllusionRom-deprecated,项目名称:android_platform_external_chromium_org_third_party_skia_src,代码行数:88,代码来源:GrPathUtils.cpp