Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19d4dd85 authored by Romain Guy's avatar Romain Guy
Browse files

Take text scale/skew into account only when rendering into a layer

3D rotations can undo scale/skew transforms; since FreeType only accepts
2x2 matrices we can end up generating very large glyphs that are drawn
at a 1:1 scale on screen. For instance, if the current transform has a
scale of 2000 set on both X and Y axis and a perspective Z factor set to
Z, the actual scale factor on screen ends up being 1. We would however
generate glyphs with a scale factor of 2000 causing the font renderer
to blow up.

Change-Id: Ia5c3618d36644e817825cb9c89e2f53aece2074e
parent cdac4972
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -2673,7 +2673,26 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
                alpha, mode, oldX, oldY);
    }

    fontRenderer.setFont(paint, pureTranslate ? mat4::identity() : *mSnapshot->transform);
    const bool hasActiveLayer = hasLayer();

    const mat4* fontTransform;
    if (CC_LIKELY(pureTranslate)) {
        fontTransform = &mat4::identity();
    } else {
        if (CC_UNLIKELY(isPerspective)) {
            // When the below condition is true, we are rendering text with a
            // perspective transform inside a layer (either an inline layer
            // created by Canvas.saveLayer() or a hardware layer.)
            if (hasActiveLayer || getTargetFbo() != 0) {
                fontTransform = mSnapshot->transform;
            } else {
                fontTransform = &mat4::identity();
            }
        } else {
            fontTransform = mSnapshot->transform;
        }
    }
    fontRenderer.setFont(paint, *fontTransform);

    // Pick the appropriate texture filtering
    bool linearFilter = !pureTranslate || fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
@@ -2701,8 +2720,6 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
    const Rect* clip = isPerspective ? NULL : mSnapshot->clipRect;
    Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);

    const bool hasActiveLayer = hasLayer();

    bool status;
    if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) {
        SkPaint paintCopy(*paint);
+24 −6
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

@SuppressWarnings({"UnusedDeclaration"})
public class Rotate3dTextActivity extends Activity {
@@ -30,8 +32,28 @@ public class Rotate3dTextActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Rotate3dTextView view = new Rotate3dTextView(this);
        setContentView(view);
        final LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        Rotate3dTextView view = new Rotate3dTextView(this);
        layout.addView(view, makeLayoutParams());

        view = new Rotate3dTextView(this);

        FrameLayout container = new FrameLayout(this);
        container.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        container.addView(view);

        layout.addView(container, makeLayoutParams());

        setContentView(layout);
    }

    private static LinearLayout.LayoutParams makeLayoutParams() {
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, 0);
        lp.weight = 1.0f;
        return lp;
    }

    public static class Rotate3dTextView extends View {
@@ -54,11 +76,7 @@ public class Rotate3dTextActivity extends Activity {

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            canvas.drawText(TEXT, getWidth() / 2.0f, getHeight() / 2.0f, mPaint);

            invalidate();
        }
    }
}