public static float inv_determinant(uiMatrix3 mat, int isPerspective) { double det; if (isPerspective != 0) { det = mat.kMScaleX * dcross(mat.kMScaleY, mat.kMPersp2, mat.kMTransY, mat.kMPersp1) + mat.kMSkewX * dcross(mat.kMTransY, mat.kMPersp0, mat.kMSkewY, mat.kMPersp2) + mat.kMTransX * dcross(mat.kMSkewY, mat.kMPersp1, mat.kMScaleY, mat.kMPersp0); } else { det = dcross(mat.kMScaleX, mat.kMScaleY, mat.kMSkewX, mat.kMSkewY); } // Since the determinant is on the order of the cube of the matrix members, // compare to the cube of the default nearly-zero constant (although an // estimate of the condition number would be better if it wasn't so expensive). if (ScalarNearlyZero((float)det, kScalarNearlyZero * kScalarNearlyZero * kScalarNearlyZero)) { return(0); } return(1.0f / (float)det); }
public static ClipElement create(int saveCount, uiPath uiPath, uiMatrix3 matrix, float scale) { ClipElement newElement = ObjectPool <ClipElement> .alloc(); newElement.saveCount = saveCount; var pathCache = uiPath.flatten(scale); var fillMesh = pathCache.getFillMesh(out newElement.convex); newElement.mesh = fillMesh.transform(matrix); var vertices = newElement.mesh.vertices; if (newElement.convex && vertices.Count == 4 && matrix.rectStaysRect() && (Mathf.Abs(vertices[0].x - vertices[1].x) < 1e-6 && Mathf.Abs(vertices[1].y - vertices[2].y) < 1e-6 && Mathf.Abs(vertices[2].x - vertices[3].x) < 1e-6 && Mathf.Abs(vertices[3].y - vertices[0].y) < 1e-6 || Mathf.Abs(vertices[0].y - vertices[1].y) < 1e-6 && Mathf.Abs(vertices[1].x - vertices[2].x) < 1e-6 && Mathf.Abs(vertices[2].y - vertices[3].y) < 1e-6 && Mathf.Abs(vertices[3].x - vertices[0].x) < 1e-6)) { newElement.isRect = true; newElement.rect = newElement.mesh.bounds; } else { newElement.isRect = false; newElement.rect = null; } return(newElement); }
static void Persp_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { D.assert(m._hasPerspective()); if (count > 0) { for (int i = 0; i < count; ++i) { var sy = src[i].dy; var sx = src[i].dx; var x = uiScalarUtils.sdot(sx, m.kMScaleX, sy, m.kMSkewX) + m.kMTransX; var y = uiScalarUtils.sdot(sx, m.kMSkewY, sy, m.kMScaleY) + m.kMTransY; var z = uiScalarUtils.sdot(sx, m.kMPersp0, sy, m.kMPersp1) + m.kMPersp2; if (z != 0) { z = 1 / z; } dst[i] = new uiOffset(x * z, y * z); } } }
void _concat(uiMatrix3 matrix) { var state = this._currentLayer.currentState; matrix = new uiMatrix3(matrix); matrix.postConcat(state.matrix.Value); state.matrix = matrix; }
public static bool ScalarsAreFinite(uiMatrix3 m) { float prod = m.kMScaleX * m.kMSkewX * m.kMTransX * m.kMSkewY * m.kMScaleY * m.kMTransY * m.kMPersp0 * m.kMPersp1 * m.kMPersp2; // At this point, prod will either be NaN or 0 return(prod == 0); // if prod is NaN, this check will return false }
static void Identity_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { D.assert(m._getType() == 0); if (dst != src && count > 0) { Array.Copy(src, dst, count); } }
public static TextBlobMesh create(TextBlob textBlob, float scale, uiMatrix3 matrix) { TextBlobMesh newMesh = ObjectPool <TextBlobMesh> .alloc(); newMesh.textBlob = textBlob; newMesh.scale = scale; newMesh.matrix = matrix; return(newMesh); }
public uiMatrix3 getGradientMat(uiMatrix3 mat) { if (this.matrix != null) { mat.postConcat(this.matrix.Value); } mat.postConcat(this.ptsToUnit); return(mat); }
public uiMatrix3 getShaderMat(uiMatrix3 mat) { if (this.matrix != null) { mat.postConcat(this.matrix.Value); } mat.postScale(1f / this.image.width, 1f / this.image.height); return(mat); }
static void Trans_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { D.assert(m._getType() <= TypeMask.kTranslate_Mask); if (count > 0) { var tx = m.getTranslateX(); var ty = m.getTranslateY(); for (int i = 0; i < count; ++i) { dst[i] = new uiOffset(src[i].dx + tx, src[i].dy + ty); } } }
static void Scale_pts(uiMatrix3 m, ref uiOffset[] dst, ref uiOffset[] src, int count) { D.assert(m._getType() <= (TypeMask.kScale_Mask | TypeMask.kTranslate_Mask)); if (count > 0) { var tx = m.getTranslateX(); var ty = m.getTranslateY(); var sx = m.getScaleX(); var sy = m.getScaleY(); for (int i = 0; i < count; ++i) { dst[i] = new uiOffset(src[i].dx * sx + tx, src[i].dy * sy + ty); } } }
public static float getScaleX(uiMatrix3 matrix) { // ignore perspective parameters for now. if (matrix.isIdentity()) { return(1.0f); } if (matrix.getSkewY() == 0) { return(matrix.getScaleX()); } var x = matrix.getScaleX(); var y = matrix.getSkewY(); return(Mathf.Sqrt(x * x + y * y)); }
public static float getScale(uiMatrix3 matrix) { var scaleX = getScaleX(matrix); var scaleY = getScaleY(matrix); if (scaleX == 1.0) { return(scaleY); } if (scaleY == 1.0) { return(scaleX); } // geometric mean of len0 and len1. return(Mathf.Sqrt(scaleX * scaleY)); }
static void Affine_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { D.assert(m._getType() != TypeMask.kPerspective_Mask); if (count > 0) { var tx = m.getTranslateX(); var ty = m.getTranslateY(); var sx = m.getScaleX(); var sy = m.getScaleY(); var kx = m.getSkewX(); var ky = m.getSkewY(); for (int i = 0; i < count; ++i) { dst[i] = new uiOffset( src[i].dx * sx + src[i].dy * kx + tx, src[i].dx * ky + src[i].dy * sy + ty); } } }
void _drawTextBlob(TextBlob?textBlob, uiOffset offset, uiPaint paint) { D.assert(textBlob != null); var state = this._currentLayer.currentState; var scale = state.scale * this._devicePixelRatio; var matrix = new uiMatrix3(state.matrix.Value); matrix.preTranslate(offset.dx, offset.dy); var mesh = TextBlobMesh.create(textBlob.Value, scale, matrix); var textBlobBounds = matrix.mapRect(uiRectHelper.fromRect(textBlob.Value.boundsInText)); // request font texture so text mesh could be generated correctly var style = textBlob.Value.style; var font = FontManager.instance.getOrCreate(style.fontFamily, style.fontWeight, style.fontStyle).font; var fontSizeToLoad = Mathf.CeilToInt(style.UnityFontSize * scale); var subText = textBlob.Value.text.Substring(textBlob.Value.textOffset, textBlob.Value.textSize); Texture tex = null; bool notEmoji = !char.IsHighSurrogate(subText[0]) && !EmojiUtils.isSingleCharEmoji(subText[0]); if (notEmoji) { font.RequestCharactersInTextureSafe(subText, fontSizeToLoad, style.UnityFontStyle); tex = font.material.mainTexture; } if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0) { this._drawWithMaskFilter(textBlobBounds, paint, paint.maskFilter.Value, null, null, false, 0, 0, tex, textBlobBounds, mesh, notEmoji, this.___drawTextDrawMeshCallback); return; } this._drawTextDrawMeshCallback(paint, null, null, false, 0, 0, tex, textBlobBounds, mesh, notEmoji); }
public void clipPath(uiPath uiPath, uiMatrix3 matrix, float scale) { var element = ClipElement.create(this._saveCount, uiPath, matrix, scale); this._pushElement(element); }
void _setMatrix(uiMatrix3 matrix) { var state = this._currentLayer.currentState; state.matrix = new uiMatrix3(matrix); }
public _uiMatrixImageFilter(uiMatrix3 transform, FilterMode filterMode) { this.transform = transform; this.filterMode = filterMode; }
public static uiImageFilter matrix(uiMatrix3 transform, FilterMode filterMode = FilterMode.Bilinear) { return(new _uiMatrixImageFilter(transform, filterMode)); }