1 /* |
1 /* |
2 * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
45 * Marlin RendererEngine implementation (derived from Pisces) |
45 * Marlin RendererEngine implementation (derived from Pisces) |
46 */ |
46 */ |
47 public final class MarlinRenderingEngine extends RenderingEngine |
47 public final class MarlinRenderingEngine extends RenderingEngine |
48 implements MarlinConst |
48 implements MarlinConst |
49 { |
49 { |
50 private static enum NormMode { |
50 // slightly slower ~2% if enabled stroker clipping (lines) but skipping cap / join handling is few percents faster in specific cases |
|
51 static final boolean DISABLE_2ND_STROKER_CLIPPING = true; |
|
52 |
|
53 static final boolean DO_TRACE_PATH = false; |
|
54 |
|
55 static final boolean DO_CLIP = MarlinProperties.isDoClip(); |
|
56 static final boolean DO_CLIP_FILL = true; |
|
57 static final boolean DO_CLIP_RUNTIME_ENABLE = MarlinProperties.isDoClipRuntimeFlag(); |
|
58 |
|
59 private static final float MIN_PEN_SIZE = 1.0f / MIN_SUBPIXELS; |
|
60 |
|
61 static final float UPPER_BND = Float.MAX_VALUE / 2.0f; |
|
62 static final float LOWER_BND = -UPPER_BND; |
|
63 |
|
64 private enum NormMode { |
51 ON_WITH_AA { |
65 ON_WITH_AA { |
52 @Override |
66 @Override |
53 PathIterator getNormalizingPathIterator(final RendererContext rdrCtx, |
67 PathIterator getNormalizingPathIterator(final RendererContext rdrCtx, |
54 final PathIterator src) |
68 final PathIterator src) |
55 { |
69 { |
77 }; |
91 }; |
78 |
92 |
79 abstract PathIterator getNormalizingPathIterator(RendererContext rdrCtx, |
93 abstract PathIterator getNormalizingPathIterator(RendererContext rdrCtx, |
80 PathIterator src); |
94 PathIterator src); |
81 } |
95 } |
82 |
|
83 private static final float MIN_PEN_SIZE = 1.0f / NORM_SUBPIXELS; |
|
84 |
|
85 static final float UPPER_BND = Float.MAX_VALUE / 2.0f; |
|
86 static final float LOWER_BND = -UPPER_BND; |
|
87 |
|
88 static final boolean DO_CLIP = MarlinProperties.isDoClip(); |
|
89 static final boolean DO_CLIP_FILL = true; |
|
90 |
|
91 static final boolean DO_TRACE_PATH = false; |
|
92 |
|
93 static final boolean DO_CLIP_RUNTIME_ENABLE = MarlinProperties.isDoClipRuntimeFlag(); |
|
94 |
96 |
95 /** |
97 /** |
96 * Public constructor |
98 * Public constructor |
97 */ |
99 */ |
98 public MarlinRenderingEngine() { |
100 public MarlinRenderingEngine() { |
417 |
419 |
418 // deltaTransformConsumer may adjust the clip rectangle: |
420 // deltaTransformConsumer may adjust the clip rectangle: |
419 pc2d = transformerPC2D.deltaTransformConsumer(pc2d, strokerat); |
421 pc2d = transformerPC2D.deltaTransformConsumer(pc2d, strokerat); |
420 |
422 |
421 // stroker will adjust the clip rectangle (width / miter limit): |
423 // stroker will adjust the clip rectangle (width / miter limit): |
422 pc2d = rdrCtx.stroker.init(pc2d, width, caps, join, miterlimit, scale); |
424 pc2d = rdrCtx.stroker.init(pc2d, width, caps, join, miterlimit, scale, |
|
425 (dashes == null)); |
|
426 |
|
427 // Curve Monotizer: |
|
428 rdrCtx.monotonizer.init(width); |
423 |
429 |
424 if (dashes != null) { |
430 if (dashes != null) { |
425 if (!recycleDashes) { |
431 if (!recycleDashes) { |
426 dashLen = dashes.length; |
432 dashLen = dashes.length; |
427 } |
433 } |
|
434 if (DO_TRACE_PATH) { |
|
435 pc2d = transformerPC2D.traceDasher(pc2d); |
|
436 } |
428 pc2d = rdrCtx.dasher.init(pc2d, dashes, dashLen, dashphase, |
437 pc2d = rdrCtx.dasher.init(pc2d, dashes, dashLen, dashphase, |
429 recycleDashes); |
438 recycleDashes); |
|
439 |
|
440 if (DISABLE_2ND_STROKER_CLIPPING) { |
|
441 // disable stoker clipping |
|
442 rdrCtx.stroker.disableClipping(); |
|
443 } |
|
444 |
430 } else if (rdrCtx.doClip && (caps != Stroker.CAP_BUTT)) { |
445 } else if (rdrCtx.doClip && (caps != Stroker.CAP_BUTT)) { |
431 if (DO_TRACE_PATH) { |
446 if (DO_TRACE_PATH) { |
432 pc2d = transformerPC2D.traceClosedPathDetector(pc2d); |
447 pc2d = transformerPC2D.traceClosedPathDetector(pc2d); |
433 } |
448 } |
434 |
449 |
623 } |
638 } |
624 |
639 |
625 private static void pathTo(final RendererContext rdrCtx, final PathIterator pi, |
640 private static void pathTo(final RendererContext rdrCtx, final PathIterator pi, |
626 PathConsumer2D pc2d) |
641 PathConsumer2D pc2d) |
627 { |
642 { |
|
643 if (USE_PATH_SIMPLIFIER) { |
|
644 // Use path simplifier at the first step |
|
645 // to remove useless points |
|
646 pc2d = rdrCtx.pathSimplifier.init(pc2d); |
|
647 } |
|
648 |
628 // mark context as DIRTY: |
649 // mark context as DIRTY: |
629 rdrCtx.dirty = true; |
650 rdrCtx.dirty = true; |
630 |
651 |
631 pathToLoop(rdrCtx.float6, pi, pc2d); |
652 pathToLoop(rdrCtx.float6, pi, pc2d); |
632 |
653 |
847 |
868 |
848 if (DO_TRACE_PATH) { |
869 if (DO_TRACE_PATH) { |
849 // trace Input: |
870 // trace Input: |
850 pc2d = rdrCtx.transformerPC2D.traceInput(pc2d); |
871 pc2d = rdrCtx.transformerPC2D.traceInput(pc2d); |
851 } |
872 } |
852 |
|
853 // TODO: subdivide quad/cubic curves into monotonic curves ? |
|
854 pathTo(rdrCtx, pi, pc2d); |
873 pathTo(rdrCtx, pi, pc2d); |
855 |
874 |
856 } else { |
875 } else { |
857 // draw shape with given stroke: |
876 // draw shape with given stroke: |
858 r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), |
877 r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), |
1068 logInfo("sun.java2d.renderer.useRef = " |
1087 logInfo("sun.java2d.renderer.useRef = " |
1069 + refType); |
1088 + refType); |
1070 |
1089 |
1071 logInfo("sun.java2d.renderer.edges = " |
1090 logInfo("sun.java2d.renderer.edges = " |
1072 + MarlinConst.INITIAL_EDGES_COUNT); |
1091 + MarlinConst.INITIAL_EDGES_COUNT); |
1073 logInfo("sun.java2d.renderer.pixelsize = " |
1092 logInfo("sun.java2d.renderer.pixelWidth = " |
1074 + MarlinConst.INITIAL_PIXEL_DIM); |
1093 + MarlinConst.INITIAL_PIXEL_WIDTH); |
|
1094 logInfo("sun.java2d.renderer.pixelHeight = " |
|
1095 + MarlinConst.INITIAL_PIXEL_HEIGHT); |
1075 |
1096 |
1076 logInfo("sun.java2d.renderer.subPixel_log2_X = " |
1097 logInfo("sun.java2d.renderer.subPixel_log2_X = " |
1077 + MarlinConst.SUBPIXEL_LG_POSITIONS_X); |
1098 + MarlinConst.SUBPIXEL_LG_POSITIONS_X); |
1078 logInfo("sun.java2d.renderer.subPixel_log2_Y = " |
1099 logInfo("sun.java2d.renderer.subPixel_log2_Y = " |
1079 + MarlinConst.SUBPIXEL_LG_POSITIONS_Y); |
1100 + MarlinConst.SUBPIXEL_LG_POSITIONS_Y); |
1099 + MarlinCache.RLE_MIN_WIDTH); |
1120 + MarlinCache.RLE_MIN_WIDTH); |
1100 |
1121 |
1101 // optimisation parameters |
1122 // optimisation parameters |
1102 logInfo("sun.java2d.renderer.useSimplifier = " |
1123 logInfo("sun.java2d.renderer.useSimplifier = " |
1103 + MarlinConst.USE_SIMPLIFIER); |
1124 + MarlinConst.USE_SIMPLIFIER); |
|
1125 logInfo("sun.java2d.renderer.usePathSimplifier= " |
|
1126 + MarlinConst.USE_PATH_SIMPLIFIER); |
|
1127 logInfo("sun.java2d.renderer.pathSimplifier.pixTol = " |
|
1128 + MarlinProperties.getPathSimplifierPixelTolerance()); |
1104 |
1129 |
1105 logInfo("sun.java2d.renderer.clip = " |
1130 logInfo("sun.java2d.renderer.clip = " |
1106 + MarlinProperties.isDoClip()); |
1131 + MarlinProperties.isDoClip()); |
1107 logInfo("sun.java2d.renderer.clip.runtime.enable = " |
1132 logInfo("sun.java2d.renderer.clip.runtime.enable = " |
1108 + MarlinProperties.isDoClipRuntimeFlag()); |
1133 + MarlinProperties.isDoClipRuntimeFlag()); |
|
1134 |
|
1135 logInfo("sun.java2d.renderer.clip.subdivider = " |
|
1136 + MarlinProperties.isDoClipSubdivider()); |
|
1137 logInfo("sun.java2d.renderer.clip.subdivider.minLength = " |
|
1138 + MarlinProperties.getSubdividerMinLength()); |
1109 |
1139 |
1110 // debugging parameters |
1140 // debugging parameters |
1111 logInfo("sun.java2d.renderer.doStats = " |
1141 logInfo("sun.java2d.renderer.doStats = " |
1112 + MarlinConst.DO_STATS); |
1142 + MarlinConst.DO_STATS); |
1113 logInfo("sun.java2d.renderer.doMonitors = " |
1143 logInfo("sun.java2d.renderer.doMonitors = " |
1122 + MarlinConst.LOG_CREATE_CONTEXT); |
1152 + MarlinConst.LOG_CREATE_CONTEXT); |
1123 logInfo("sun.java2d.renderer.logUnsafeMalloc = " |
1153 logInfo("sun.java2d.renderer.logUnsafeMalloc = " |
1124 + MarlinConst.LOG_UNSAFE_MALLOC); |
1154 + MarlinConst.LOG_UNSAFE_MALLOC); |
1125 |
1155 |
1126 // quality settings |
1156 // quality settings |
|
1157 logInfo("sun.java2d.renderer.curve_len_err = " |
|
1158 + MarlinProperties.getCurveLengthError()); |
1127 logInfo("sun.java2d.renderer.cubic_dec_d2 = " |
1159 logInfo("sun.java2d.renderer.cubic_dec_d2 = " |
1128 + MarlinProperties.getCubicDecD2()); |
1160 + MarlinProperties.getCubicDecD2()); |
1129 logInfo("sun.java2d.renderer.cubic_inc_d1 = " |
1161 logInfo("sun.java2d.renderer.cubic_inc_d1 = " |
1130 + MarlinProperties.getCubicIncD1()); |
1162 + MarlinProperties.getCubicIncD1()); |
1131 logInfo("sun.java2d.renderer.quad_dec_d2 = " |
1163 logInfo("sun.java2d.renderer.quad_dec_d2 = " |