1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-25 06:17:33 +00:00

Fix archimate monochrome issue

This commit is contained in:
Arnaud Roques 2022-04-02 16:33:30 +02:00
parent bbf173962a
commit 35b05e7e6c
20 changed files with 127 additions and 87 deletions

View File

@ -38,7 +38,6 @@ package net.sourceforge.plantuml;
import java.util.Map;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColorSet;
public interface ISkinSimple extends SpriteContainer {
@ -59,8 +58,6 @@ public interface ISkinSimple extends SpriteContainer {
public LineBreakStrategy wrapWidth();
public ColorMapper getColorMapper();
public void copyAllFrom(ISkinSimple other);
public double minClassWidth();

View File

@ -37,13 +37,16 @@ package net.sourceforge.plantuml;
import net.sourceforge.plantuml.api.ThemeStyle;
import net.sourceforge.plantuml.sprite.Sprite;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
public interface SpriteContainer extends SvgCharSizeHack {
public Sprite getSprite(String name);
public Guillemet guillemet();
public ThemeStyle getThemeStyle();
public ColorMapper getColorMapper();
}

View File

@ -42,6 +42,7 @@ import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.sprite.Sprite;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class AtomSprite extends AbstractAtom implements Atom {
@ -50,8 +51,11 @@ public class AtomSprite extends AbstractAtom implements Atom {
private final double scale;
private final Url url;
private final HColor color;
private final ColorMapper colorMapper;
public AtomSprite(HColor newColor, double scale, FontConfiguration fontConfiguration, Sprite sprite, Url url) {
public AtomSprite(HColor newColor, double scale, FontConfiguration fontConfiguration, Sprite sprite, Url url,
ColorMapper colorMapper) {
this.colorMapper = colorMapper;
this.scale = scale;
this.sprite = sprite;
this.url = url;
@ -59,7 +63,7 @@ public class AtomSprite extends AbstractAtom implements Atom {
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
return sprite.asTextBlock(color, scale).calculateDimension(stringBounder);
return sprite.asTextBlock(color, scale, colorMapper).calculateDimension(stringBounder);
}
public double getStartingAltitude(StringBounder stringBounder) {
@ -70,7 +74,7 @@ public class AtomSprite extends AbstractAtom implements Atom {
if (url != null) {
ug.startUrl(url);
}
sprite.asTextBlock(color, scale).drawU(ug);
sprite.asTextBlock(color, scale, colorMapper).drawU(ug);
if (url != null) {
ug.closeUrl();
}

View File

@ -119,7 +119,8 @@ public class AtomTextUtils {
final Sprite sprite = skinSimple.getSprite(valSprite);
if (sprite != null) {
final double scale = Parser.getScale(m.group(4), 1);
result.add(new AtomSprite(null, scale, fontConfiguration, sprite, url));
result.add(
new AtomSprite(null, scale, fontConfiguration, sprite, url, skinSimple.getColorMapper()));
}
} else if (valImg != null) {
final double scale = Parser.getScale(m.group(6), 1);

View File

@ -255,7 +255,7 @@ public class StripeSimple implements Stripe {
public void addSprite(String src, double scale, HColor color) {
final Sprite sprite = skinParam.getSprite(src);
if (sprite != null)
atoms.add(new AtomSprite(color, scale, fontConfiguration, sprite, null));
atoms.add(new AtomSprite(color, scale, fontConfiguration, sprite, null, skinParam.getColorMapper()));
}
public void addOpenIcon(String src, double scale, HColor color) {

View File

@ -72,9 +72,9 @@ public class Stereotype implements CharSequence {
}
private static void checkLabel(String label) {
if (label.startsWith("<<") == false || label.endsWith(">>") == false) {
if (label.startsWith("<<") == false || label.endsWith(">>") == false)
throw new IllegalArgumentException(label);
}
}
public static Stereotype build(String label) {
@ -103,14 +103,14 @@ public class Stereotype implements CharSequence {
}
public final TextBlock getSprite(SpriteContainer container) {
if (decoration.spriteName == null || container == null) {
if (decoration.spriteName == null || container == null)
return null;
}
final Sprite tmp = container.getSprite(decoration.spriteName);
if (tmp == null) {
if (tmp == null)
return null;
}
return tmp.asTextBlock(getHtmlColor(), decoration.spriteScale);
return tmp.asTextBlock(getHtmlColor(), decoration.spriteScale, container.getColorMapper());
}
public boolean isWithOOSymbol() {
@ -122,9 +122,8 @@ public class Stereotype implements CharSequence {
final Pattern p = Pattern.compile("\\<\\<\\s?((?:\\<&\\w+\\>|[^<>])+?)\\s?\\>\\>");
final Matcher m = p.matcher(decoration.label);
while (m.find()) {
while (m.find())
result.add(m.group(1));
}
return Collections.unmodifiableList(result);
}
@ -135,9 +134,9 @@ public class Stereotype implements CharSequence {
@Override
public String toString() {
if (decoration.character == 0) {
if (decoration.character == 0)
return decoration.label;
}
return decoration.character + " " + decoration.label;
}
@ -162,20 +161,20 @@ public class Stereotype implements CharSequence {
}
public String getLabel(Guillemet guillemet) {
if (isWithOOSymbol()) {
if (isWithOOSymbol())
return null;
}
if (decoration.spriteName != null && decoration.spriteName.startsWith("archimate/")) {
if (decoration.spriteName != null && decoration.spriteName.startsWith("archimate/"))
return guillemet.manageGuillemet("<<" + decoration.spriteName.substring("archimate/".length()) + ">>");
}
return guillemet.manageGuillemet(decoration.label);
}
public List<String> getLabels(Guillemet guillemet) {
final String labelLocal = getLabel(Guillemet.DOUBLE_COMPARATOR);
if (labelLocal == null) {
if (labelLocal == null)
return Collections.emptyList();
}
return StereotypeDecoration.cutLabels(labelLocal, guillemet);
}
@ -191,21 +190,20 @@ public class Stereotype implements CharSequence {
public List<String> getStyleNames() {
final List<String> labels = getLabels(Guillemet.NONE);
if (labels == null) {
if (labels == null)
return Collections.emptyList();
}
return Collections.unmodifiableList(labels);
}
public PackageStyle getPackageStyle() {
if (automaticPackageStyle == false) {
if (automaticPackageStyle == false)
return null;
}
for (PackageStyle p : EnumSet.allOf(PackageStyle.class)) {
if (("<<" + p + ">>").equalsIgnoreCase(decoration.label)) {
for (PackageStyle p : EnumSet.allOf(PackageStyle.class))
if (("<<" + p + ">>").equalsIgnoreCase(decoration.label))
return p;
}
}
return null;
}

View File

@ -134,19 +134,18 @@ public class CommandArchimate extends SingleLineCommand2<DescriptionDiagram> {
final String displayRaw = arg.getLazzy("DISPLAY", 0);
String display = displayRaw;
if (display == null) {
if (display == null)
display = code.getName();
}
display = StringUtils.eventuallyRemoveStartingAndEndingDoubleQuote(display);
entity.setDisplay(Display.getWithNewlines(display));
entity.setUSymbol(USymbols.ARCHIMATE);
if (icon != null) {
if (icon != null)
entity.setStereotype(
Stereotype.build("<<$archimate/" + icon + ">>", diagram.getSkinParam().getCircledCharacterRadius(),
diagram.getSkinParam().getFont(null, false, FontParam.CIRCLED_CHARACTER),
diagram.getSkinParam().getIHtmlColorSet()));
}
final Colors colors = color().getColor(diagram.getSkinParam().getThemeStyle(), arg,
diagram.getSkinParam().getIHtmlColorSet());

View File

@ -74,7 +74,8 @@ class SingleLine extends AbstractTextBlock implements Line {
} else if (cmd instanceof SpriteCommand) {
final Sprite sprite = spriteContainer.getSprite(((SpriteCommand) cmd).getSprite());
if (sprite != null)
result.blocs.add(sprite.asTextBlock(fontConfiguration.getColor(), 1));
result.blocs
.add(sprite.asTextBlock(fontConfiguration.getColor(), 1, spriteContainer.getColorMapper()));
} else if (cmd instanceof FontChange) {
fontConfiguration = ((FontChange) cmd).apply(fontConfiguration);

View File

@ -118,14 +118,21 @@ public class LatexBuilder implements ScientificEquation {
return new LatexImage(icon, this.scale * scale, foregroundColor, backgroundColor);
}
@Override
public MutableImage muteColor(Color newColor) {
return this;
}
@Override
public MutableImage muteTransparentColor(Color newColor) {
return this;
}
@Override
public MutableImage monochrome() {
return this;
}
}
public String getSource() {

View File

@ -94,7 +94,7 @@ public class ListSpriteDiagram extends UmlDiagram {
final Sprite sprite = getSkinParam().getSprite(n);
TextBlock blockName = Display.create(n).create(FontConfiguration.blackBlueTrue(UFont.sansSerif(14)),
HorizontalAlignment.LEFT, getSkinParam());
TextBlock tb = sprite.asTextBlock(HColorUtils.BLACK, 1.0);
TextBlock tb = sprite.asTextBlock(HColorUtils.BLACK, 1.0, getSkinParam().getColorMapper());
tb = TextBlockUtils.mergeTB(tb, blockName, HorizontalAlignment.CENTER);
tb.drawU(ug.apply(new UTranslate(x, y)));
final Dimension2D dim = tb.calculateDimension(ug.getStringBounder());

View File

@ -36,10 +36,11 @@
package net.sourceforge.plantuml.sprite;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public interface Sprite {
public TextBlock asTextBlock(final HColor color, double scale);
public TextBlock asTextBlock(final HColor color, double scale, ColorMapper colorMapper);
}

View File

@ -124,7 +124,7 @@ public class SpriteColor implements Sprite {
return new UImage(new PixelImage(im, AffineTransformType.TYPE_BILINEAR));
}
public TextBlock asTextBlock(final HColor color, final double scale) {
public TextBlock asTextBlock(final HColor color, final double scale, ColorMapper colorMapper) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {

View File

@ -35,13 +35,13 @@
*/
package net.sourceforge.plantuml.sprite;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import net.sourceforge.plantuml.Dimension2DDouble;
import net.sourceforge.plantuml.awt.geom.Dimension2D;
import net.sourceforge.plantuml.graphic.AbstractTextBlock;
import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
@ -50,8 +50,9 @@ import net.sourceforge.plantuml.ugraphic.AffineTransformType;
import net.sourceforge.plantuml.ugraphic.PixelImage;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImage;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.ColorMapperMonochrome;
import net.sourceforge.plantuml.ugraphic.color.HColor;
import net.sourceforge.plantuml.ugraphic.color.HColorSimple;
public class SpriteImage implements Sprite {
@ -61,15 +62,19 @@ public class SpriteImage implements Sprite {
this.img = new UImage(new PixelImage(Objects.requireNonNull(img), AffineTransformType.TYPE_BILINEAR));
}
public TextBlock asTextBlock(final HColor color, final double scale) {
public TextBlock asTextBlock(final HColor color, final double scale, final ColorMapper colorMapper) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {
if (color == null) {
if (colorMapper instanceof ColorMapperMonochrome) {
ug.draw(img.monochrome().scale(scale));
} else if (color == null)
ug.draw(img.scale(scale));
} else {
ug.draw(img.muteColor(((HColorSimple) color).getColor999()).scale(scale));
}
else
ug.draw(img.muteColor(colorMapper.toColor(color)).scale(scale));
// ug.draw(img.muteColor(((HColorSimple) color).getColor999()).scale(scale));
}
public Dimension2D calculateDimension(StringBounder stringBounder) {
@ -79,13 +84,13 @@ public class SpriteImage implements Sprite {
}
public static Sprite fromInternal(String name) {
if (name.endsWith(".png")) {
if (name.endsWith(".png"))
throw new IllegalArgumentException();
}
final InputStream is = getInternalSprite(name + ".png");
if (is == null) {
if (is == null)
return null;
}
try {
return new SpriteImage(SImageIO.read(is));
} catch (IOException e) {

View File

@ -213,7 +213,7 @@ public class SpriteMonochrome implements Sprite {
return new UImage(new PixelImage(im, AffineTransformType.TYPE_BILINEAR));
}
public TextBlock asTextBlock(final HColor color, final double scale) {
public TextBlock asTextBlock(final HColor color, final double scale, ColorMapper colorMapper) {
return new AbstractTextBlock() {
public void drawU(UGraphic ug) {

View File

@ -43,6 +43,7 @@ import net.sourceforge.plantuml.graphic.StringBounder;
import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.ugraphic.UGraphic;
import net.sourceforge.plantuml.ugraphic.UImageSvg;
import net.sourceforge.plantuml.ugraphic.color.ColorMapper;
import net.sourceforge.plantuml.ugraphic.color.HColor;
public class SpriteSvg implements Sprite {
@ -55,7 +56,7 @@ public class SpriteSvg implements Sprite {
// this.img = new UImageSvg(new SvgString(svg, 1));
}
public TextBlock asTextBlock(final HColor color, final double scale) {
public TextBlock asTextBlock(final HColor color, final double scale, ColorMapper colorMapper) {
final UImageSvg img = new UImageSvg(svg, scale);
return new AbstractTextBlock() {

View File

@ -143,7 +143,7 @@ public class StdlibDiagram extends UmlDiagram {
final Sprite sprite = getSkinParam().getSprite(n);
TextBlock blockName = Display.create(n).create(FontConfiguration.blackBlueTrue(UFont.sansSerif(14)),
HorizontalAlignment.LEFT, getSkinParam());
TextBlock tb = sprite.asTextBlock(getBlack(), 1.0);
TextBlock tb = sprite.asTextBlock(getBlack(), 1.0, getSkinParam().getColorMapper());
tb = TextBlockUtils.mergeTB(tb, blockName, HorizontalAlignment.CENTER);
tb.drawU(ug.apply(new UTranslate(x, y)));
final Dimension2D dim = tb.calculateDimension(ug.getStringBounder());

View File

@ -48,4 +48,6 @@ public interface MutableImage {
public MutableImage muteTransparentColor(Color newColor);
public MutableImage monochrome();
}

View File

@ -60,14 +60,16 @@ public class PixelImage implements MutableImage {
this.type = Objects.requireNonNull(type);
}
@Override
public MutableImage withScale(double scale) {
return new PixelImage(bufferedImageScale1, type, this.scale * scale);
}
@Override
public final BufferedImage getImage() {
if (scale == 1) {
if (scale == 1)
return bufferedImageScale1;
}
if (cache == null) {
final int w = (int) Math.round(bufferedImageScale1.getWidth() * scale);
final int h = (int) Math.round(bufferedImageScale1.getHeight() * scale);
@ -80,61 +82,77 @@ public class PixelImage implements MutableImage {
return cache;
}
@Override
public MutableImage monochrome() {
final BufferedImage copy = deepCopy();
for (int i = 0; i < bufferedImageScale1.getWidth(); i++)
for (int j = 0; j < bufferedImageScale1.getHeight(); j++) {
final int color = bufferedImageScale1.getRGB(i, j);
final int rgb = getRgb(color);
final int grayScale = ColorUtils.getGrayScale(rgb);
final int gray = grayScale + grayScale << 8 + grayScale << 16;
final int a = getA(color);
copy.setRGB(i, j, gray + a);
}
return new PixelImage(copy, type, scale);
}
@Override
public MutableImage muteColor(Color newColor) {
if (newColor == null) {
if (newColor == null)
return this;
}
int darkerRgb = getDarkerRgb();
final BufferedImage copy = deepCopy();
for (int i = 0; i < bufferedImageScale1.getWidth(); i++) {
for (int i = 0; i < bufferedImageScale1.getWidth(); i++)
for (int j = 0; j < bufferedImageScale1.getHeight(); j++) {
final int color = bufferedImageScale1.getRGB(i, j);
final int rgb = getRgb(color);
final int a = getA(color);
if (a != 0 && rgb == darkerRgb) {
if (a != 0 && rgb == darkerRgb)
copy.setRGB(i, j, newColor.getRGB() + a);
}
}
}
return new PixelImage(copy, type, scale);
}
@Override
public MutableImage muteTransparentColor(Color newColor) {
if (newColor == null) {
if (newColor == null)
newColor = Color.WHITE;
}
final BufferedImage copy = deepCopy();
for (int i = 0; i < bufferedImageScale1.getWidth(); i++) {
for (int i = 0; i < bufferedImageScale1.getWidth(); i++)
for (int j = 0; j < bufferedImageScale1.getHeight(); j++) {
final int color = bufferedImageScale1.getRGB(i, j);
final int a = getA(color);
if (a == 0) {
if (a == 0)
copy.setRGB(i, j, newColor.getRGB());
}
}
}
return new PixelImage(copy, type, scale);
}
private int getDarkerRgb() {
int darkerRgb = -1;
for (int i = 0; i < bufferedImageScale1.getWidth(); i++) {
for (int i = 0; i < bufferedImageScale1.getWidth(); i++)
for (int j = 0; j < bufferedImageScale1.getHeight(); j++) {
final int color = bufferedImageScale1.getRGB(i, j);
final int rgb = getRgb(color);
final int a = getA(color);
if (a != mask_a__) {
if (a != mask_a__)
continue;
}
// if (isTransparent(color)) {
// continue;
// }
final int gray = ColorUtils.getGrayScale(rgb);
if (darkerRgb == -1 || gray < ColorUtils.getGrayScale(darkerRgb)) {
if (darkerRgb == -1 || gray < ColorUtils.getGrayScale(darkerRgb))
darkerRgb = rgb;
}
}
}
return darkerRgb;
}
@ -161,11 +179,10 @@ public class PixelImage implements MutableImage {
private BufferedImage deepCopy() {
final BufferedImage result = new BufferedImage(bufferedImageScale1.getWidth(), bufferedImageScale1.getHeight(),
BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < this.bufferedImageScale1.getWidth(); i++) {
for (int j = 0; j < this.bufferedImageScale1.getHeight(); j++) {
for (int i = 0; i < this.bufferedImageScale1.getWidth(); i++)
for (int j = 0; j < this.bufferedImageScale1.getHeight(); j++)
result.setRGB(i, j, bufferedImageScale1.getRGB(i, j));
}
}
return result;
}

View File

@ -95,4 +95,8 @@ public class UImage implements UShape {
return new UImage(image.muteTransparentColor(newColor), rawFileName, formula);
}
public UImage monochrome() {
return new UImage(image.monochrome(), rawFileName, formula);
}
}

View File

@ -46,16 +46,16 @@ public class ColorMapperMonochrome extends AbstractColorMapper implements ColorM
}
public Color toColor(HColor htmlColor) {
if (htmlColor == null) {
if (htmlColor == null)
return null;
}
final Color color = new ColorMapperIdentity().toColor(htmlColor);
if (HColorUtils.isTransparent(htmlColor)) {
if (HColorUtils.isTransparent(htmlColor))
return color;
}
if (reverse && HColorUtils.isTransparent(htmlColor) == false) {
if (reverse && HColorUtils.isTransparent(htmlColor) == false)
return ColorUtils.getGrayScaleColorReverse(color);
}
return ColorUtils.getGrayScaleColor(color);
}
}