LibreOffice Module android (master) 1
SingleTileLayer.java
Go to the documentation of this file.
1/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6package org.mozilla.gecko.gfx;
7
8import android.graphics.Rect;
9import android.graphics.RectF;
10import android.graphics.Region;
11import android.graphics.RegionIterator;
12import android.opengl.GLES20;
13
14import java.nio.FloatBuffer;
15
21public class SingleTileLayer extends TileLayer {
22 private static final String LOGTAG = "GeckoSingleTileLayer";
23
24 private Rect mMask;
25
26 // To avoid excessive GC, declare some objects here that would otherwise
27 // be created and destroyed frequently during draw().
28 private final RectF mBounds;
29 private final RectF mTextureBounds;
30 private final RectF mViewport;
31 private final Rect mIntBounds;
32 private final Rect mSubRect;
33 private final RectF mSubRectF;
34 private final Region mMaskedBounds;
35 private final Rect mCropRect;
36 private final RectF mObjRectF;
37 private final float[] mCoords;
38
40 this(false, image);
41 }
42
43 public SingleTileLayer(boolean repeat, CairoImage image) {
44 this(image, repeat ? TileLayer.PaintMode.REPEAT : TileLayer.PaintMode.NORMAL);
45 }
46
47 public SingleTileLayer(CairoImage image, TileLayer.PaintMode paintMode) {
48 super(image, paintMode);
49
50 mBounds = new RectF();
51 mTextureBounds = new RectF();
52 mViewport = new RectF();
53 mIntBounds = new Rect();
54 mSubRect = new Rect();
55 mSubRectF = new RectF();
56 mMaskedBounds = new Region();
57 mCropRect = new Rect();
58 mObjRectF = new RectF();
59 mCoords = new float[20];
60 }
61
65 public void setMask(Rect aMaskRect) {
66 mMask = aMaskRect;
67 }
68
69 @Override
70 public void draw(RenderContext context) {
71 // mTextureIDs may be null here during startup if Layer.java's draw method
72 // failed to acquire the transaction lock and call performUpdates.
73 if (!initialized())
74 return;
75
76 mViewport.set(context.viewport);
77
78 if (repeats()) {
79 // If we're repeating, we want to adjust the texture bounds so that
80 // the texture repeats the correct number of times when drawn at
81 // the size of the viewport.
82 mBounds.set(getBounds(context));
83 mTextureBounds.set(0.0f, 0.0f, mBounds.width(), mBounds.height());
84 mBounds.set(0.0f, 0.0f, mViewport.width(), mViewport.height());
85 } else if (stretches()) {
86 // If we're stretching, we just want the bounds and texture bounds
87 // to fit to the page.
88 mBounds.set(context.pageRect);
90 } else {
91 mBounds.set(getBounds(context));
93 }
94
95 mBounds.roundOut(mIntBounds);
97 if (mMask != null) {
98 mMaskedBounds.op(mMask, Region.Op.DIFFERENCE);
99 if (mMaskedBounds.isEmpty())
100 return;
101 }
102
103 // XXX Possible optimisation here, form this array so we can draw it in
104 // a single call.
105 RegionIterator i = new RegionIterator(mMaskedBounds);
106 while (i.next(mSubRect)) {
107 // Compensate for rounding errors at the edge of the tile caused by
108 // the roundOut above
109 mSubRectF.set(Math.max(mBounds.left, (float)mSubRect.left),
110 Math.max(mBounds.top, (float)mSubRect.top),
111 Math.min(mBounds.right, (float)mSubRect.right),
112 Math.min(mBounds.bottom, (float)mSubRect.bottom));
113
114 // This is the left/top/right/bottom of the rect, relative to the
115 // bottom-left of the layer, to use for texture coordinates.
116 mCropRect.set(Math.round(mSubRectF.left - mBounds.left),
117 Math.round(mBounds.bottom - mSubRectF.top),
118 Math.round(mSubRectF.right - mBounds.left),
119 Math.round(mBounds.bottom - mSubRectF.bottom));
120
121 mObjRectF.set(mSubRectF.left - mViewport.left,
122 mViewport.bottom - mSubRectF.bottom,
123 mSubRectF.right - mViewport.left,
124 mViewport.bottom - mSubRectF.top);
125
127 mCropRect, mTextureBounds.width(), mTextureBounds.height());
128
129 FloatBuffer coordBuffer = context.coordBuffer;
130 int positionHandle = context.positionHandle;
131 int textureHandle = context.textureHandle;
132
133 GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
134 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
135
136 // Make sure we are at position zero in the buffer
137 coordBuffer.position(0);
138 coordBuffer.put(mCoords);
139
140 // Unbind any the current array buffer so we can use client side buffers
141 GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
142
143 // Vertex coordinates are x,y,z starting at position 0 into the buffer.
144 coordBuffer.position(0);
145 GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
146
147 // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
148 coordBuffer.position(3);
149 GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
150 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
151 }
152 }
153}
154
final void fillRectCoordBuffer(float[] dest, RectF rect, float viewWidth, float viewHeight, Rect cropRect, float texWidth, float texHeight)
This function fills in the provided dest array with values to render a texture.
Definition: Layer.java:162
RectF getBounds(RenderContext context)
Given the intrinsic size of the layer, returns the pixel boundaries of the layer rect.
Definition: Layer.java:67
Encapsulates the logic needed to draw a single textured tile.
SingleTileLayer(boolean repeat, CairoImage image)
SingleTileLayer(CairoImage image, TileLayer.PaintMode paintMode)
void setMask(Rect aMaskRect)
Set an area to mask out when rendering.
void draw(RenderContext context)
Subclasses override this function to draw the layer.
Base class for tile layers, which encapsulate the logic needed to draw textured tiles in OpenGL ES.
Definition: TileLayer.java:18
int i