Skip to content

Commit

Permalink
Merge pull request #195 from Christopher-Chianelli/multiline-text-wrap
Browse files Browse the repository at this point in the history
Exposed Text Wrapping API and added a Wrapper that wraps on bounds and new lines
  • Loading branch information
SprocketNYC authored Oct 24, 2017
2 parents ded919c + 1f86fdd commit 6543a72
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 30 deletions.
27 changes: 27 additions & 0 deletions src/main/java/com/ait/lienzo/client/core/shape/IDrawString.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Copyright (c) 2017 Ahome' Innovation Technologies. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.ait.lienzo.client.core.shape;

import com.ait.lienzo.client.core.Context2D;

/**
* An interface for drawing a string to a canvas
*/
public interface IDrawString {

void draw(Context2D c, String s, double xOffset, double lineNum);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@
package com.ait.lienzo.client.core.shape;

import com.ait.lienzo.client.core.Context2D;
import com.ait.lienzo.client.core.shape.wires.IControlHandleFactory;
import com.ait.lienzo.client.core.types.BoundingBox;
import com.ait.lienzo.client.core.types.DragBounds;
import com.ait.lienzo.client.core.types.Point2D;
import com.ait.lienzo.client.widget.DragConstraintEnforcer;
import com.ait.lienzo.shared.core.types.DragConstraint;
import com.ait.lienzo.shared.core.types.DragMode;
import com.ait.lienzo.shared.core.types.EventPropagationMode;

/**
* An interface to define Text wrapping behaviour.
Expand All @@ -34,7 +27,7 @@ public interface ITextWrapper

BoundingBox getBoundingBox();

void drawString(final Context2D context, final Attributes attr, final Text.DrawString drawCommand);
void drawString(final Context2D context, final Attributes attr, final IDrawString drawCommand);

interface Supplier<T> {

Expand Down
17 changes: 5 additions & 12 deletions src/main/java/com/ait/lienzo/client/core/shape/Text.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,10 @@
import com.ait.lienzo.client.core.types.PatternGradient;
import com.ait.lienzo.client.core.types.RadialGradient;
import com.ait.lienzo.client.core.types.TextMetrics;
import com.ait.lienzo.client.core.util.ScratchPad;
import com.ait.lienzo.shared.core.types.ShapeType;
import com.ait.lienzo.shared.core.types.TextAlign;
import com.ait.lienzo.shared.core.types.TextBaseLine;
import com.ait.lienzo.shared.core.types.TextUnit;
import com.ait.tooling.nativetools.client.collection.NFastDoubleArrayJSO;
import com.ait.tooling.nativetools.client.collection.NFastStringMap;
import com.google.gwt.json.client.JSONObject;

/**
Expand All @@ -45,7 +42,7 @@ public class Text extends Shape<Text>
{
private static final boolean GRADFILLS = LienzoCore.get().isSafariBroken();

private final DrawString STROKE = new DrawString() {
private final IDrawString STROKE = new IDrawString() {
@Override
public void draw(Context2D context, String s,
double xOffset, double lineNum) {
Expand All @@ -58,7 +55,7 @@ public void draw(Context2D context, String s,
}
};

private final DrawString FILL = new DrawString() {
private final IDrawString FILL = new IDrawString() {
@Override
public void draw(Context2D context,
String s,
Expand Down Expand Up @@ -261,7 +258,7 @@ protected boolean fill(final Context2D context, final Attributes attr, double al

drawString(context,
attr,
new DrawString() {
new IDrawString() {
@Override
public void draw(Context2D context,
String s,
Expand All @@ -277,7 +274,7 @@ public void draw(Context2D context,

drawString(context,
attr,
new DrawString() {
new IDrawString() {
@Override
public void draw(Context2D context,
String s,
Expand Down Expand Up @@ -385,7 +382,7 @@ private static final native void log(String msg)/*-{
console.log(msg);
}-*/;

private void drawString(final Context2D context, final Attributes attr, DrawString drawCommand)
private void drawString(final Context2D context, final Attributes attr, IDrawString drawCommand)
{
wrapper.drawString(context,attr,drawCommand);
}
Expand Down Expand Up @@ -666,8 +663,4 @@ public Text create(JSONObject node, ValidationContext ctx) throws ValidationExce
return new Text(node, ctx);
}
}

interface DrawString {
void draw(Context2D c, String s, double xOffset, double lineNum);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
Copyright (c) 2017 Ahome' Innovation Technologies. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.ait.lienzo.client.core.shape;

import java.util.ArrayList;

import com.ait.lienzo.client.core.Context2D;
import com.ait.lienzo.client.core.types.BoundingBox;
import com.ait.lienzo.shared.core.types.TextAlign;
import com.ait.lienzo.shared.core.types.TextBaseLine;
import com.ait.lienzo.shared.core.types.TextUnit;

/**
* ITextWrapper implementation that wraps text when a line exceeds the width of the provided boundary.
*/
public class TextBoundsAndLineBreaksWrap extends TextBoundsWrap {
public TextBoundsAndLineBreaksWrap(final Text text) {
super(text);
}

public TextBoundsAndLineBreaksWrap(final Text text,
final BoundingBox wrapBoundaries) {
super(text, wrapBoundaries);
}

public TextBoundsAndLineBreaksWrap(final Supplier<String> textSupplier,
final Supplier<Double> fontSizeSupplier,
final Supplier<String> fontStyleSupplier,
final Supplier<String> fontFamilySupplier,
final Supplier<TextUnit> textUnitSupplier,
final Supplier<TextBaseLine> textBaseLineSupplier,
final Supplier<TextAlign> textAlignSupplier,
final BoundingBox wrapBoundaries) {
super(textSupplier,
fontSizeSupplier,
fontStyleSupplier,
fontFamilySupplier,
textUnitSupplier,
textBaseLineSupplier,
textAlignSupplier,
wrapBoundaries);
}

@Override
public void drawString(final Context2D context,
final Attributes attr,
final IDrawString drawCommand) {
final BoundingBox wrapBoundaries = getWrapBoundaries();
final String[] textLines = attr.getText().split("\\r?\\n");
if (textLines.length < 1) {
return;
}

final ArrayList<String> lines = new ArrayList<>();
for (String line : textLines) {
String[] words = line.split("\\s");
if (words.length < 1) {
lines.add("");
continue;
}
final StringBuilder nextLine = new StringBuilder(words[0]);

for (int i = 1; i < words.length; i++) {
if (getBoundingBoxForString(nextLine + " " + words[i]).getWidth() <= wrapBoundaries.getWidth()) {
nextLine.append(" ").append(words[i]);
} else {
lines.add(nextLine.toString());
nextLine.setLength(words[i].length());
nextLine.replace(0,
words[i].length(),
words[i]);
}
}
lines.add(nextLine.toString());
}

double xOffset = 0;

switch (textAlignSupplier.get()) {
case START:
case LEFT:
xOffset = 0;
break;

case CENTER:
xOffset = wrapBoundaries.getWidth() / 2;
break;

case END:
case RIGHT:
xOffset = wrapBoundaries.getWidth();
break;
}

double yOffset = 0.8;

for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
int toPad = (int) Math.round((wrapBoundaries.getWidth() - getBoundingBoxForString(line).getWidth()) / getBoundingBoxForString(" ").getWidth());
line = TextUtils.padString(line,
line.length() + toPad,
' ',
textAlignSupplier.get());
drawCommand.draw(context,
line,
xOffset,
i + yOffset);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public TextBoundsWrap setWrapBoundaries(final BoundingBox boundaries) {

@Override
public BoundingBox getBoundingBox() {
final String[] words = textSupplier.get().split(" ");
final String[] words = textSupplier.get().split("\\s");
if (words.length < 1) {
return wrapBoundaries;
}
Expand All @@ -98,8 +98,9 @@ public BoundingBox getBoundingBox() {
@Override
public void drawString(final Context2D context,
final Attributes attr,
final Text.DrawString drawCommand) {
final String[] words = attr.getText().split(" ");
final IDrawString drawCommand) {
final String[] words = attr.getText().split("\\s");

if (words.length < 1) {
return;
}
Expand Down Expand Up @@ -136,6 +137,7 @@ public void drawString(final Context2D context,
xOffset = wrapBoundaries.getWidth();
break;
}
double yOffset = 0.8;

for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
Expand All @@ -147,7 +149,7 @@ public void drawString(final Context2D context,
drawCommand.draw(context,
line,
xOffset,
i + 0.8);
i + yOffset);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public BoundingBox getBoundingBox() {
@Override
public void drawString(final Context2D context,
final Attributes attr,
final Text.DrawString drawCommand) {
final IDrawString drawCommand) {
final String text = attr.getText();
if (text == null || text.isEmpty()) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ protected BoundingBox getBoundingBoxForString(final String string) {
@Override
public void drawString(final Context2D context,
final Attributes attr,
final Text.DrawString drawCommand) {
final IDrawString drawCommand) {
drawCommand.draw(context,
attr.getText(),
0,
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/ait/lienzo/client/core/shape/TextUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static native NFastDoubleArrayJSO getTextOffsets(CanvasPixelArray data, int wide
return [ top - base, bot - base ];
}-*/;

static final NFastDoubleArrayJSO getTextOffsets(final String font, final TextBaseLine baseline)
public static final NFastDoubleArrayJSO getTextOffsets(final String font, final TextBaseLine baseline)
{
FORBOUNDS.getContext().setTextFont(font);

Expand Down Expand Up @@ -99,7 +99,7 @@ static final NFastDoubleArrayJSO getTextOffsets(final String font, final TextBas
return getTextOffsets(ctxt.getImageData(0, 0, w, h).getData(), w, h, m * 2);
}

static BoundingBox getBoundingBox(final String text, final double size, final String style, final String family, final TextUnit unit, final TextBaseLine baseline, final TextAlign align)
public static BoundingBox getBoundingBox(final String text, final double size, final String style, final String family, final TextUnit unit, final TextBaseLine baseline, final TextAlign align)
{
if ((null == text) || (text.isEmpty()) || (false == (size > 0)))
{
Expand Down Expand Up @@ -146,12 +146,12 @@ static BoundingBox getBoundingBox(final String text, final double size, final St
return bbox;
}

static String getFontString(final double size, final TextUnit unit, final String style, final String family)
public static String getFontString(final double size, final TextUnit unit, final String style, final String family)
{
return style + " " + size + unit.toString() + " " + family;
}

static String padString(String string, int targetSize, char padChar, TextAlign where) {
public static String padString(String string, int targetSize, char padChar, TextAlign where) {
if (string.length() >= targetSize) {
return string;
}
Expand Down

0 comments on commit 6543a72

Please sign in to comment.