1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.internal.widget.remotecompose.core; 17 18 import android.annotation.NonNull; 19 import android.annotation.Nullable; 20 21 import com.android.internal.widget.remotecompose.core.operations.paint.PaintBundle; 22 23 import java.util.HashMap; 24 25 /** Specify an abstract paint context used by RemoteCompose commands to draw */ 26 public abstract class PaintContext { 27 public static final int TEXT_MEASURE_MONOSPACE_WIDTH = 0x01; 28 public static final int TEXT_MEASURE_FONT_HEIGHT = 0x02; 29 public static final int TEXT_MEASURE_SPACES = 0x04; 30 public static final int TEXT_COMPLEX = 0x08; 31 32 protected @NonNull RemoteContext mContext; 33 private boolean mNeedsRepaint = false; 34 35 @NonNull getContext()36 public RemoteContext getContext() { 37 return mContext; 38 } 39 40 /** 41 * Returns true if the needsRepaint flag is set 42 * 43 * @return true if the document asks to be repainted 44 */ doesNeedsRepaint()45 public boolean doesNeedsRepaint() { 46 return mNeedsRepaint; 47 } 48 49 /** Clear the needsRepaint flag */ clearNeedsRepaint()50 public void clearNeedsRepaint() { 51 mNeedsRepaint = false; 52 } 53 PaintContext(@onNull RemoteContext context)54 public PaintContext(@NonNull RemoteContext context) { 55 this.mContext = context; 56 } 57 setContext(@onNull RemoteContext context)58 public void setContext(@NonNull RemoteContext context) { 59 this.mContext = context; 60 } 61 62 /** convenience function to call matrixSave() */ save()63 public void save() { 64 matrixSave(); 65 } 66 67 /** convenience function to call matrixRestore() */ restore()68 public void restore() { 69 matrixRestore(); 70 } 71 72 /** convenience function to call matrixSave() */ saveLayer(float x, float y, float width, float height)73 public void saveLayer(float x, float y, float width, float height) { 74 // TODO 75 matrixSave(); 76 } 77 78 /** 79 * Draw a bitmap 80 * 81 * @param imageId 82 * @param srcLeft 83 * @param srcTop 84 * @param srcRight 85 * @param srcBottom 86 * @param dstLeft 87 * @param dstTop 88 * @param dstRight 89 * @param dstBottom 90 * @param cdId 91 */ drawBitmap( int imageId, int srcLeft, int srcTop, int srcRight, int srcBottom, int dstLeft, int dstTop, int dstRight, int dstBottom, int cdId)92 public abstract void drawBitmap( 93 int imageId, 94 int srcLeft, 95 int srcTop, 96 int srcRight, 97 int srcBottom, 98 int dstLeft, 99 int dstTop, 100 int dstRight, 101 int dstBottom, 102 int cdId); 103 104 /** 105 * scale the following commands 106 * 107 * @param scaleX horizontal scale factor 108 * @param scaleY vertical scale factor 109 */ scale(float scaleX, float scaleY)110 public abstract void scale(float scaleX, float scaleY); 111 112 /** 113 * Rotate the following commands 114 * 115 * @param translateX horizontal translation 116 * @param translateY vertical translation 117 */ translate(float translateX, float translateY)118 public abstract void translate(float translateX, float translateY); 119 120 /** 121 * Draw an arc 122 * 123 * @param left 124 * @param top 125 * @param right 126 * @param bottom 127 * @param startAngle 128 * @param sweepAngle 129 */ drawArc( float left, float top, float right, float bottom, float startAngle, float sweepAngle)130 public abstract void drawArc( 131 float left, float top, float right, float bottom, float startAngle, float sweepAngle); 132 133 /** 134 * Draw a sector 135 * 136 * @param left 137 * @param top 138 * @param right 139 * @param bottom 140 * @param startAngle 141 * @param sweepAngle 142 */ drawSector( float left, float top, float right, float bottom, float startAngle, float sweepAngle)143 public abstract void drawSector( 144 float left, float top, float right, float bottom, float startAngle, float sweepAngle); 145 146 /** 147 * Draw a bitmap 148 * 149 * @param id 150 * @param left 151 * @param top 152 * @param right 153 * @param bottom 154 */ drawBitmap(int id, float left, float top, float right, float bottom)155 public abstract void drawBitmap(int id, float left, float top, float right, float bottom); 156 157 /** 158 * Draw a circle 159 * 160 * @param centerX 161 * @param centerY 162 * @param radius 163 */ drawCircle(float centerX, float centerY, float radius)164 public abstract void drawCircle(float centerX, float centerY, float radius); 165 166 /** 167 * Draw a line 168 * 169 * @param x1 170 * @param y1 171 * @param x2 172 * @param y2 173 */ drawLine(float x1, float y1, float x2, float y2)174 public abstract void drawLine(float x1, float y1, float x2, float y2); 175 176 /** 177 * Draw an oval 178 * 179 * @param left 180 * @param top 181 * @param right 182 * @param bottom 183 */ drawOval(float left, float top, float right, float bottom)184 public abstract void drawOval(float left, float top, float right, float bottom); 185 186 /** 187 * Draw a path 188 * 189 * @param id the path id 190 * @param start starting point of the path where we start drawing it 191 * @param end ending point of the path where we stop drawing it 192 */ drawPath(int id, float start, float end)193 public abstract void drawPath(int id, float start, float end); 194 195 /** 196 * Draw a rectangle 197 * 198 * @param left left coordinate of the rectangle 199 * @param top top coordinate of the rectangle 200 * @param right right coordinate of the rectangle 201 * @param bottom bottom coordinate of the rectangle 202 */ drawRect(float left, float top, float right, float bottom)203 public abstract void drawRect(float left, float top, float right, float bottom); 204 205 /** this caches the paint to a paint stack */ savePaint()206 public abstract void savePaint(); 207 208 /** This restores the paint form the paint stack */ restorePaint()209 public abstract void restorePaint(); 210 211 /** 212 * Replace the current paint with the PaintBundle 213 * 214 * @param paint 215 */ replacePaint(PaintBundle paint)216 public abstract void replacePaint(PaintBundle paint); 217 218 /** 219 * draw a round rect 220 * 221 * @param left left coordinate of the rectangle 222 * @param top top coordinate of the rectangle 223 * @param right right coordinate of the rectangle 224 * @param bottom bottom coordinate of the rectangle 225 * @param radiusX horizontal radius of the rounded corner 226 * @param radiusY vertical radius of the rounded corner 227 */ drawRoundRect( float left, float top, float right, float bottom, float radiusX, float radiusY)228 public abstract void drawRoundRect( 229 float left, float top, float right, float bottom, float radiusX, float radiusY); 230 231 /** 232 * Draw the text glyphs on the provided path 233 * 234 * @param textId id of the text 235 * @param pathId id of the path 236 * @param hOffset horizontal offset 237 * @param vOffset vertical offset 238 */ drawTextOnPath(int textId, int pathId, float hOffset, float vOffset)239 public abstract void drawTextOnPath(int textId, int pathId, float hOffset, float vOffset); 240 241 /** 242 * Return the dimensions (left, top, right, bottom). Relative to a drawTextRun x=0, y=0; 243 * 244 * @param textId 245 * @param start 246 * @param end if end is -1 it means the whole string 247 * @param flags how to measure: 248 * <ul> 249 * <li>TEXT_MEASURE_MONOSPACE_WIDTH - measure as a monospace font 250 * <li>TEXT_MEASURE_FULL_HEIGHT - measure bounds of the given string using the max ascend 251 * and descent of the font (not just of the measured text). 252 * <li>TEXT_MEASURE_SPACES - make sure to include leading/trailing spaces in the measure 253 * <li>TEXT_MEASURE_COMPLEX - complex text 254 * </ul> 255 * 256 * @param bounds the bounds (left, top, right, bottom) 257 */ getTextBounds( int textId, int start, int end, int flags, @NonNull float[] bounds)258 public abstract void getTextBounds( 259 int textId, int start, int end, int flags, @NonNull float[] bounds); 260 261 /** 262 * Compute complex text layout 263 * 264 * @param textId 265 * @param start 266 * @param end if end is -1 it means the whole string 267 * @param alignment draw the text aligned start/center/end in the available space if > text 268 * length 269 * @param overflow overflow behavior when text length > max width 270 * @param maxLines maximum number of lines to display 271 * @param maxWidth maximum width to layout the text 272 * @param flags how to measure: 273 * <ul> 274 * <li>TEXT_MEASURE_MONOSPACE_WIDTH - measure as a monospace font 275 * <li>TEXT_MEASURE_FULL_HEIGHT - measure bounds of the given string using the max ascend 276 * and descent of the font (not just of the measured text). 277 * <li>TEXT_MEASURE_SPACES - make sure to include leading/trailing spaces in the measure 278 * <li>TEXT_MEASURE_COMPLEX - complex text 279 * </ul> 280 * 281 * @return an instance of a ComputedTextLayout (typically if complex text drawing is used) 282 */ layoutComplexText( int textId, int start, int end, int alignment, int overflow, int maxLines, float maxWidth, int flags)283 public abstract Platform.ComputedTextLayout layoutComplexText( 284 int textId, 285 int start, 286 int end, 287 int alignment, 288 int overflow, 289 int maxLines, 290 float maxWidth, 291 int flags); 292 293 /** 294 * Draw a text starting ast x,y 295 * 296 * @param textId reference to the text 297 * @param start 298 * @param end 299 * @param contextStart 300 * @param contextEnd 301 * @param x 302 * @param y 303 * @param rtl 304 */ drawTextRun( int textId, int start, int end, int contextStart, int contextEnd, float x, float y, boolean rtl)305 public abstract void drawTextRun( 306 int textId, 307 int start, 308 int end, 309 int contextStart, 310 int contextEnd, 311 float x, 312 float y, 313 boolean rtl); 314 315 /** 316 * Draw a complex text (multilines, etc.) 317 * 318 * @param computedTextLayout pre-computed text layout 319 */ drawComplexText(Platform.ComputedTextLayout computedTextLayout)320 public abstract void drawComplexText(Platform.ComputedTextLayout computedTextLayout); 321 322 /** 323 * Draw an interpolation between two paths 324 * 325 * @param path1Id 326 * @param path2Id 327 * @param tween 0.0 = is path1 1.0 is path2 328 * @param start 329 * @param stop 330 */ drawTweenPath( int path1Id, int path2Id, float tween, float start, float stop)331 public abstract void drawTweenPath( 332 int path1Id, int path2Id, float tween, float start, float stop); 333 334 /** 335 * Interpolate between two path and return the resulting path 336 * 337 * @param out the interpolated path 338 * @param path1 start path 339 * @param path2 end path 340 * @param tween interpolation value from 0 (start path) to 1 (end path) 341 */ tweenPath(int out, int path1, int path2, float tween)342 public abstract void tweenPath(int out, int path1, int path2, float tween); 343 344 /** 345 * Perform a between two path and return the resulting path 346 * 347 * @param out the interpolated path 348 * @param path1 start path 349 * @param path2 end path 350 * @param operation 0 = difference , 1 = intersection, 2 = reverse_difference, 3 = union, 4 = 351 * xor 352 */ combinePath(int out, int path1, int path2, byte operation)353 public abstract void combinePath(int out, int path1, int path2, byte operation); 354 355 /** 356 * This applies changes to the current paint 357 * 358 * @param mPaintData the list of changes 359 */ applyPaint(@onNull PaintBundle mPaintData)360 public abstract void applyPaint(@NonNull PaintBundle mPaintData); 361 362 /** 363 * Scale the rendering by scaleX and saleY (1.0 = no scale). Scaling is done about 364 * centerX,centerY. 365 * 366 * @param scaleX 367 * @param scaleY 368 * @param centerX 369 * @param centerY 370 */ matrixScale(float scaleX, float scaleY, float centerX, float centerY)371 public abstract void matrixScale(float scaleX, float scaleY, float centerX, float centerY); 372 373 /** 374 * Translate the rendering 375 * 376 * @param translateX 377 * @param translateY 378 */ matrixTranslate(float translateX, float translateY)379 public abstract void matrixTranslate(float translateX, float translateY); 380 381 /** 382 * Skew the rendering 383 * 384 * @param skewX 385 * @param skewY 386 */ matrixSkew(float skewX, float skewY)387 public abstract void matrixSkew(float skewX, float skewY); 388 389 /** 390 * Rotate the rendering. Note rotates are cumulative. 391 * 392 * @param rotate angle to rotate 393 * @param pivotX x-coordinate about which to rotate 394 * @param pivotY y-coordinate about which to rotate 395 */ matrixRotate(float rotate, float pivotX, float pivotY)396 public abstract void matrixRotate(float rotate, float pivotX, float pivotY); 397 398 /** Save the current state of the transform */ matrixSave()399 public abstract void matrixSave(); 400 401 /** Restore the previously saved state of the transform */ matrixRestore()402 public abstract void matrixRestore(); 403 404 /** 405 * Set the clip to a rectangle. Drawing outside the current clip region will have no effect 406 * 407 * @param left 408 * @param top 409 * @param right 410 * @param bottom 411 */ clipRect(float left, float top, float right, float bottom)412 public abstract void clipRect(float left, float top, float right, float bottom); 413 414 /** 415 * Clip based on a path. 416 * 417 * @param pathId 418 * @param regionOp 419 */ clipPath(int pathId, int regionOp)420 public abstract void clipPath(int pathId, int regionOp); 421 422 /** 423 * Clip based ona round rect 424 * 425 * @param width 426 * @param height 427 * @param topStart 428 * @param topEnd 429 * @param bottomStart 430 * @param bottomEnd 431 */ roundedClipRect( float width, float height, float topStart, float topEnd, float bottomStart, float bottomEnd)432 public abstract void roundedClipRect( 433 float width, 434 float height, 435 float topStart, 436 float topEnd, 437 float bottomStart, 438 float bottomEnd); 439 440 /** Reset the paint */ reset()441 public abstract void reset(); 442 443 /** 444 * Returns true if the context is in debug mode 445 * 446 * @return true if in debug mode, false otherwise 447 */ isDebug()448 public boolean isDebug() { 449 return mContext.isDebug(); 450 } 451 452 /** 453 * Returns true if layout animations are enabled 454 * 455 * @return true if animations are enabled, false otherwise 456 */ isAnimationEnabled()457 public boolean isAnimationEnabled() { 458 return mContext.isAnimationEnabled(); 459 } 460 461 /** 462 * Utility function to log comments 463 * 464 * @param content the content to log 465 */ log(@onNull String content)466 public void log(@NonNull String content) { 467 System.out.println("[LOG] " + content); 468 } 469 470 /** Indicates the document needs to be repainted */ needsRepaint()471 public void needsRepaint() { 472 mNeedsRepaint = true; 473 } 474 475 /** 476 * Starts a graphics layer 477 * 478 * @param w 479 * @param h 480 */ startGraphicsLayer(int w, int h)481 public abstract void startGraphicsLayer(int w, int h); 482 483 /** 484 * Starts a graphics layer 485 * 486 * @param attributes 487 */ setGraphicsLayer(@onNull HashMap<Integer, Object> attributes)488 public abstract void setGraphicsLayer(@NonNull HashMap<Integer, Object> attributes); 489 490 /** Ends a graphics layer */ endGraphicsLayer()491 public abstract void endGraphicsLayer(); 492 isVisualDebug()493 public boolean isVisualDebug() { 494 return mContext.isVisualDebug(); 495 } 496 497 /** 498 * Returns a String from an id 499 * 500 * @param textID 501 * @return the string if found 502 */ getText(int textID)503 public abstract @Nullable String getText(int textID); 504 505 /** 506 * Returns true if the document has been encoded for at least the given version MAJOR.MINOR 507 * 508 * @param major major version number 509 * @param minor minor version number 510 * @param patch patch version number 511 * @return true if the document was written at least with the given version 512 */ supportsVersion(int major, int minor, int patch)513 public boolean supportsVersion(int major, int minor, int patch) { 514 return mContext.supportsVersion(major, minor, patch); 515 } 516 } 517