LibreOffice Module android (master) 1
NinePatchTileLayer.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.RectF;
9import android.opengl.GLES20;
10
11import java.nio.FloatBuffer;
12
19public class NinePatchTileLayer extends TileLayer {
20 private static final int PATCH_SIZE = 16;
21 private static final int TEXTURE_SIZE = 64;
22
24 super(image, PaintMode.NORMAL);
25 }
26
27 @Override
28 public void draw(RenderContext context) {
29 if (!initialized())
30 return;
31
32 GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
33 GLES20.glEnable(GLES20.GL_BLEND);
34
35 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
36 drawPatches(context);
37 }
38
39 private void drawPatches(RenderContext context) {
40 /*
41 * We divide the nine-patch bitmap up as follows:
42 *
43 * +---+---+---+
44 * | 0 | 1 | 2 |
45 * +---+---+---+
46 * | 3 | | 4 |
47 * +---+---+---+
48 * | 5 | 6 | 7 |
49 * +---+---+---+
50 */
51
52 // page is the rect of the "missing" center spot in the picture above
53 RectF page = context.pageRect;
54
55 drawPatch(context, 0, PATCH_SIZE * 3, /* 0 */
56 page.left - PATCH_SIZE, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
57 drawPatch(context, PATCH_SIZE, PATCH_SIZE * 3, /* 1 */
58 page.left, page.top - PATCH_SIZE, page.width(), PATCH_SIZE);
59 drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 3, /* 2 */
60 page.right, page.top - PATCH_SIZE, PATCH_SIZE, PATCH_SIZE);
61 drawPatch(context, 0, PATCH_SIZE * 2, /* 3 */
62 page.left - PATCH_SIZE, page.top, PATCH_SIZE, page.height());
63 drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 2, /* 4 */
64 page.right, page.top, PATCH_SIZE, page.height());
65 drawPatch(context, 0, PATCH_SIZE, /* 5 */
66 page.left - PATCH_SIZE, page.bottom, PATCH_SIZE, PATCH_SIZE);
67 drawPatch(context, PATCH_SIZE, PATCH_SIZE, /* 6 */
68 page.left, page.bottom, page.width(), PATCH_SIZE);
69 drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE, /* 7 */
70 page.right, page.bottom, PATCH_SIZE, PATCH_SIZE);
71 }
72
73 private void drawPatch(RenderContext context, int textureX, int textureY,
74 float tileX, float tileY, float tileWidth, float tileHeight) {
75 RectF viewport = context.viewport;
76 float viewportHeight = viewport.height();
77 float drawX = tileX - viewport.left;
78 float drawY = viewportHeight - (tileY + tileHeight - viewport.top);
79
80 float[] coords = {
81 //x, y, z, texture_x, texture_y
82 drawX/viewport.width(), drawY/viewport.height(), 0,
83 textureX/(float)TEXTURE_SIZE, textureY/(float)TEXTURE_SIZE,
84
85 drawX/viewport.width(), (drawY+tileHeight)/viewport.height(), 0,
86 textureX/(float)TEXTURE_SIZE, (textureY+PATCH_SIZE)/(float)TEXTURE_SIZE,
87
88 (drawX+tileWidth)/viewport.width(), drawY/viewport.height(), 0,
89 (textureX+PATCH_SIZE)/(float)TEXTURE_SIZE, textureY/(float)TEXTURE_SIZE,
90
91 (drawX+tileWidth)/viewport.width(), (drawY+tileHeight)/viewport.height(), 0,
92 (textureX+PATCH_SIZE)/(float)TEXTURE_SIZE, (textureY+PATCH_SIZE)/(float)TEXTURE_SIZE
93
94 };
95
96 // Get the buffer and handles from the context
97 FloatBuffer coordBuffer = context.coordBuffer;
98 int positionHandle = context.positionHandle;
99 int textureHandle = context.textureHandle;
100
101 // Make sure we are at position zero in the buffer in case other draw methods did not clean
102 // up after themselves
103 coordBuffer.position(0);
104 coordBuffer.put(coords);
105
106 // Unbind any the current array buffer so we can use client side buffers
107 GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
108
109 // Vertex coordinates are x,y,z starting at position 0 into the buffer.
110 coordBuffer.position(0);
111 GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
112
113 // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
114 coordBuffer.position(3);
115 GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
116
117 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
118 GLES20.GL_CLAMP_TO_EDGE);
119 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
120 GLES20.GL_CLAMP_TO_EDGE);
121
122 // Use bilinear filtering for both magnification and minimization of the texture. This
123 // applies only to the shadow layer so we do not incur a high overhead.
124 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
125 GLES20.GL_LINEAR);
126 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
127 GLES20.GL_LINEAR);
128
129 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
130 }
131}
Encapsulates the logic needed to draw a nine-patch bitmap using OpenGL ES.
void draw(RenderContext context)
Subclasses override this function to draw the layer.
void drawPatch(RenderContext context, int textureX, int textureY, float tileX, float tileY, float tileWidth, float tileHeight)
Base class for tile layers, which encapsulate the logic needed to draw textured tiles in OpenGL ES.
Definition: TileLayer.java:18