mirror of
https://github.com/olgamiller/SSTVEncoder2.git
synced 2026-04-21 06:03:53 +00:00
Initial commit
This commit is contained in:
commit
6a5cf6b221
83 changed files with 5443 additions and 0 deletions
40
app/src/main/java/om/sstvencoder/TextOverlay/IReader.java
Normal file
40
app/src/main/java/om/sstvencoder/TextOverlay/IReader.java
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 Olga Miller <olga.rgb@gmail.com>
|
||||
|
||||
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 om.sstvencoder.TextOverlay;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IReader {
|
||||
void beginRootObject() throws IOException;
|
||||
|
||||
void beginObject() throws IOException;
|
||||
|
||||
void endObject() throws IOException;
|
||||
|
||||
void beginArray() throws IOException;
|
||||
|
||||
void endArray() throws IOException;
|
||||
|
||||
boolean hasNext() throws IOException;
|
||||
|
||||
String readString() throws IOException;
|
||||
|
||||
boolean readBoolean() throws IOException;
|
||||
|
||||
float readFloat() throws IOException;
|
||||
|
||||
int readInt() throws IOException;
|
||||
}
|
||||
40
app/src/main/java/om/sstvencoder/TextOverlay/IWriter.java
Normal file
40
app/src/main/java/om/sstvencoder/TextOverlay/IWriter.java
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 Olga Miller <olga.rgb@gmail.com>
|
||||
|
||||
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 om.sstvencoder.TextOverlay;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface IWriter {
|
||||
void beginRootObject() throws IOException;
|
||||
|
||||
void beginObject(@NonNull String name) throws IOException;
|
||||
|
||||
void endObject() throws IOException;
|
||||
|
||||
void beginArray(@NonNull String name) throws IOException;
|
||||
|
||||
void endArray() throws IOException;
|
||||
|
||||
void write(@NonNull String name, String value) throws IOException;
|
||||
|
||||
void write(@NonNull String name, boolean value) throws IOException;
|
||||
|
||||
void write(@NonNull String name, float value) throws IOException;
|
||||
|
||||
void write(@NonNull String name, int value) throws IOException;
|
||||
}
|
||||
96
app/src/main/java/om/sstvencoder/TextOverlay/Label.java
Normal file
96
app/src/main/java/om/sstvencoder/TextOverlay/Label.java
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Copyright 2017 Olga Miller <olga.rgb@gmail.com>
|
||||
|
||||
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 om.sstvencoder.TextOverlay;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Label implements Serializable {
|
||||
private String mText;
|
||||
private float mTextSize;
|
||||
private String mFamilyName;
|
||||
private boolean mBold, mItalic;
|
||||
private int mForeColor, mBackColor;
|
||||
|
||||
public Label() {
|
||||
mText = "";
|
||||
mTextSize = 2.0f;
|
||||
mFamilyName = null;
|
||||
mBold = true;
|
||||
mItalic = false;
|
||||
mForeColor = Color.BLACK;
|
||||
mBackColor = Color.TRANSPARENT;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return mText;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
if (text != null)
|
||||
mText = text;
|
||||
}
|
||||
|
||||
public float getTextSize() {
|
||||
return mTextSize;
|
||||
}
|
||||
|
||||
public void setTextSize(float textSize) {
|
||||
if (textSize > 0f)
|
||||
mTextSize = textSize;
|
||||
}
|
||||
|
||||
public String getFamilyName() {
|
||||
return mFamilyName;
|
||||
}
|
||||
|
||||
public void setFamilyName(String familyName) {
|
||||
mFamilyName = familyName;
|
||||
}
|
||||
|
||||
public boolean getBold() {
|
||||
return mBold;
|
||||
}
|
||||
|
||||
public void setBold(boolean bold) {
|
||||
mBold = bold;
|
||||
}
|
||||
|
||||
public boolean getItalic() {
|
||||
return mItalic;
|
||||
}
|
||||
|
||||
public void setItalic(boolean italic) {
|
||||
mItalic = italic;
|
||||
}
|
||||
|
||||
public int getForeColor() {
|
||||
return mForeColor;
|
||||
}
|
||||
|
||||
public void setForeColor(int color) {
|
||||
mForeColor = color;
|
||||
}
|
||||
|
||||
public int getBackColor() {
|
||||
return mBackColor;
|
||||
}
|
||||
|
||||
public void setBackColor(int color) {
|
||||
mBackColor = color;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
Copyright 2017 Olga Miller <olga.rgb@gmail.com>
|
||||
|
||||
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 om.sstvencoder.TextOverlay;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import om.sstvencoder.Utility;
|
||||
|
||||
public class LabelCollection {
|
||||
private class Size {
|
||||
private float mW, mH;
|
||||
|
||||
Size(float w, float h) {
|
||||
mW = w;
|
||||
mH = h;
|
||||
}
|
||||
|
||||
float width() {
|
||||
return mW;
|
||||
}
|
||||
|
||||
float height() {
|
||||
return mH;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<LabelContainer> mLabels;
|
||||
private Size mScreenSize;
|
||||
private float mTextSizeFactor;
|
||||
private LabelContainer mActiveLabel, mEditLabel;
|
||||
private float mPreviousX, mPreviousY;
|
||||
|
||||
public LabelCollection() {
|
||||
mLabels = new LinkedList<>();
|
||||
mPreviousX = 0f;
|
||||
mPreviousY = 0f;
|
||||
}
|
||||
|
||||
public void update(float w, float h) {
|
||||
if (mScreenSize != null) {
|
||||
float x = (w - mScreenSize.width()) / 2f;
|
||||
float y = (h - mScreenSize.height()) / 2f;
|
||||
for (LabelContainer label : mLabels)
|
||||
label.offset(x, y);
|
||||
}
|
||||
mScreenSize = new Size(w, h);
|
||||
mTextSizeFactor = getTextSizeFactor(w, h);
|
||||
for (LabelContainer label : mLabels)
|
||||
label.update(mTextSizeFactor, w, h);
|
||||
}
|
||||
|
||||
private float getTextSizeFactor(float w, float h) {
|
||||
Rect bounds = Utility.getEmbeddedRect((int) w, (int) h, 320, 240);
|
||||
return 0.1f * bounds.height();
|
||||
}
|
||||
|
||||
public void draw(Canvas canvas) {
|
||||
for (LabelContainer label : mLabels)
|
||||
label.draw(canvas);
|
||||
if (mActiveLabel != null)
|
||||
mActiveLabel.drawActive(canvas);
|
||||
}
|
||||
|
||||
public void draw(Canvas canvas, Rect src, Rect dst) {
|
||||
for (LabelContainer label : mLabels)
|
||||
label.draw(canvas, src, dst);
|
||||
}
|
||||
|
||||
public boolean moveLabelBegin(float x, float y) {
|
||||
mActiveLabel = find(x, y);
|
||||
if (mActiveLabel == null)
|
||||
return false;
|
||||
mLabels.remove(mActiveLabel);
|
||||
mPreviousX = x;
|
||||
mPreviousY = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void moveLabel(float x, float y) {
|
||||
mActiveLabel.offset(x - mPreviousX, y - mPreviousY);
|
||||
mActiveLabel.update(mTextSizeFactor, mScreenSize.width(), mScreenSize.height());
|
||||
mPreviousX = x;
|
||||
mPreviousY = y;
|
||||
}
|
||||
|
||||
public void moveLabelEnd() {
|
||||
mLabels.add(mActiveLabel);
|
||||
mActiveLabel = null;
|
||||
mPreviousX = 0f;
|
||||
mPreviousY = 0f;
|
||||
}
|
||||
|
||||
public Label editLabelBegin(float x, float y) {
|
||||
mEditLabel = find(x, y);
|
||||
if (mEditLabel == null) {
|
||||
mEditLabel = new LabelContainer(new Label());
|
||||
mEditLabel.offset(x, y);
|
||||
}
|
||||
return mEditLabel.getContent();
|
||||
}
|
||||
|
||||
public void editLabelEnd(Label label) {
|
||||
if (label != null) { // not canceled
|
||||
if ("".equals(label.getText().trim())) {
|
||||
if (mLabels.contains(mEditLabel))
|
||||
mLabels.remove(mEditLabel);
|
||||
} else {
|
||||
if (!mLabels.contains(mEditLabel))
|
||||
mLabels.add(mEditLabel);
|
||||
mEditLabel.setContent(label);
|
||||
mEditLabel.update(mTextSizeFactor, mScreenSize.width(), mScreenSize.height());
|
||||
}
|
||||
}
|
||||
mEditLabel = null;
|
||||
}
|
||||
|
||||
private LabelContainer find(float x, float y) {
|
||||
for (LabelContainer label : mLabels) {
|
||||
if (label.contains(x, y))
|
||||
return label;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void add(LabelContainer label) {
|
||||
if (mLabels.size() == 0)
|
||||
mLabels.add(label);
|
||||
else
|
||||
mLabels.add(0, label);
|
||||
}
|
||||
|
||||
public void write(@NonNull IWriter writer) throws IOException {
|
||||
writer.beginRootObject();
|
||||
{
|
||||
writer.write("width", mScreenSize.width());
|
||||
writer.write("height", mScreenSize.height());
|
||||
writer.beginArray("labels");
|
||||
{
|
||||
for (LabelContainer label : mLabels)
|
||||
label.write(writer);
|
||||
}
|
||||
writer.endArray();
|
||||
}
|
||||
writer.endObject();
|
||||
}
|
||||
|
||||
public void read(@NonNull IReader reader) throws IOException {
|
||||
reader.beginRootObject();
|
||||
{
|
||||
float w = reader.readFloat();
|
||||
float h = reader.readFloat();
|
||||
reader.beginArray();
|
||||
{
|
||||
while (reader.hasNext()) {
|
||||
LabelContainer label = new LabelContainer(new Label());
|
||||
label.read(reader);
|
||||
add(label);
|
||||
}
|
||||
}
|
||||
reader.endArray();
|
||||
update(w, h);
|
||||
}
|
||||
reader.endObject();
|
||||
}
|
||||
}
|
||||
117
app/src/main/java/om/sstvencoder/TextOverlay/LabelContainer.java
Normal file
117
app/src/main/java/om/sstvencoder/TextOverlay/LabelContainer.java
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
Copyright 2017 Olga Miller <olga.rgb@gmail.com>
|
||||
|
||||
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 om.sstvencoder.TextOverlay;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class LabelContainer {
|
||||
private Label mLabel;
|
||||
private LabelPainter mPainter;
|
||||
private float mX, mY; // left-bottom corner
|
||||
|
||||
LabelContainer(@NonNull Label label) {
|
||||
mLabel = label;
|
||||
mPainter = new LabelPainter(label);
|
||||
mX = mY = 0f;
|
||||
}
|
||||
|
||||
boolean contains(float x, float y) {
|
||||
return mPainter.getBounds().contains(x, y);
|
||||
}
|
||||
|
||||
void draw(Canvas canvas) {
|
||||
mPainter.draw(canvas);
|
||||
}
|
||||
|
||||
void drawActive(Canvas canvas) {
|
||||
mPainter.drawActive(canvas);
|
||||
}
|
||||
|
||||
void draw(Canvas canvas, Rect src, Rect dst) {
|
||||
mPainter.draw(canvas, src, dst);
|
||||
}
|
||||
|
||||
void offset(float x, float y) {
|
||||
mX += x;
|
||||
mY += y;
|
||||
}
|
||||
|
||||
void update(float textSizeFactor, float screenW, float screenH) {
|
||||
mPainter.update(textSizeFactor, screenW, screenH, mX, mY);
|
||||
}
|
||||
|
||||
Label getContent() {
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
void setContent(@NonNull Label label) {
|
||||
mLabel = label;
|
||||
mPainter.setLabel(label);
|
||||
}
|
||||
|
||||
void write(IWriter writer) throws IOException {
|
||||
writer.beginRootObject();
|
||||
{
|
||||
writer.write("position_x", mX);
|
||||
writer.write("position_y", mY);
|
||||
writer.beginObject("label");
|
||||
{
|
||||
writeLabel(writer, mLabel);
|
||||
}
|
||||
writer.endObject();
|
||||
}
|
||||
writer.endObject();
|
||||
}
|
||||
|
||||
void read(IReader reader) throws IOException {
|
||||
reader.beginRootObject();
|
||||
{
|
||||
mX = reader.readFloat();
|
||||
mY = reader.readFloat();
|
||||
reader.beginObject();
|
||||
{
|
||||
readLabel(reader, mLabel);
|
||||
}
|
||||
reader.endObject();
|
||||
}
|
||||
reader.endObject();
|
||||
}
|
||||
|
||||
private void writeLabel(IWriter writer, Label label) throws IOException {
|
||||
writer.write("text", label.getText());
|
||||
writer.write("text_size", label.getTextSize());
|
||||
writer.write("family_name", label.getFamilyName());
|
||||
writer.write("bold", label.getBold());
|
||||
writer.write("italic", label.getItalic());
|
||||
writer.write("fore_color", label.getForeColor());
|
||||
writer.write("back_color", label.getBackColor());
|
||||
}
|
||||
|
||||
private void readLabel(IReader reader, Label label) throws IOException {
|
||||
label.setText(reader.readString());
|
||||
label.setTextSize(reader.readFloat());
|
||||
label.setFamilyName(reader.readString());
|
||||
label.setBold(reader.readBoolean());
|
||||
label.setItalic(reader.readBoolean());
|
||||
label.setForeColor(reader.readInt());
|
||||
label.setBackColor(reader.readInt());
|
||||
}
|
||||
}
|
||||
|
||||
303
app/src/main/java/om/sstvencoder/TextOverlay/LabelPainter.java
Normal file
303
app/src/main/java/om/sstvencoder/TextOverlay/LabelPainter.java
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
Copyright 2017 Olga Miller <olga.rgb@gmail.com>
|
||||
|
||||
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 om.sstvencoder.TextOverlay;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
class LabelPainter {
|
||||
private interface IDrawer {
|
||||
void draw(Canvas canvas);
|
||||
|
||||
void drawShadow(Canvas canvas);
|
||||
|
||||
void draw(Canvas canvas, Rect src, Rect dst);
|
||||
|
||||
RectF getBounds();
|
||||
}
|
||||
|
||||
private class InDrawer implements IDrawer {
|
||||
private float mSizeFactor;
|
||||
private float mX, mY;
|
||||
|
||||
private InDrawer(float sizeFactor, float x, float y) {
|
||||
mSizeFactor = sizeFactor;
|
||||
mX = x;
|
||||
mY = y;
|
||||
setPaintSettings(mSizeFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
canvas.drawText(mLabel.getText(), mX, mY, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawShadow(Canvas canvas) {
|
||||
RectF bounds = new RectF(getBounds());
|
||||
float rx = 10f;
|
||||
float ry = 10f;
|
||||
|
||||
mPaint.setColor(Color.LTGRAY);
|
||||
mPaint.setAlpha(100);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawRoundRect(bounds, rx, ry, mPaint);
|
||||
|
||||
mPaint.setAlpha(255);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
|
||||
mPaint.setColor(Color.RED);
|
||||
bounds.inset(-5.0f, -5.0f);
|
||||
canvas.drawRoundRect(bounds, rx, ry, mPaint);
|
||||
|
||||
mPaint.setColor(Color.GREEN);
|
||||
bounds.inset(1.0f, 1.0f);
|
||||
canvas.drawRoundRect(bounds, rx, ry, mPaint);
|
||||
|
||||
mPaint.setColor(Color.BLUE);
|
||||
bounds.inset(1.0f, 1.0f);
|
||||
canvas.drawRoundRect(bounds, rx, ry, mPaint);
|
||||
|
||||
setPaintSettings(mSizeFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas, Rect src, Rect dst) {
|
||||
float factor = (dst.height() / (float) src.height());
|
||||
float x = (mX - src.left) * factor;
|
||||
float y = (mY - src.top) * factor;
|
||||
setTextSize(factor * mSizeFactor);
|
||||
canvas.drawText(mLabel.getText(), x, y, mPaint);
|
||||
setTextSize(mSizeFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RectF getBounds() {
|
||||
RectF bounds = new RectF(getTextBounds());
|
||||
bounds.offset(mX, mY);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private Rect getTextBounds() {
|
||||
Rect bounds = new Rect();
|
||||
String text = mLabel.getText();
|
||||
mPaint.getTextBounds(text, 0, text.length(), bounds);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
private void setPaintSettings(float sizeFactor) {
|
||||
mPaint.setAlpha(255);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
mPaint.setColor(mLabel.getForeColor());
|
||||
mPaint.setTypeface(Typeface.create(mLabel.getFamilyName(), getTypeface()));
|
||||
setTextSize(sizeFactor);
|
||||
}
|
||||
|
||||
private void setTextSize(float sizeFactor) {
|
||||
mPaint.setTextSize(mLabel.getTextSize() * sizeFactor);
|
||||
}
|
||||
|
||||
private int getTypeface() {
|
||||
int typeface = Typeface.NORMAL;
|
||||
|
||||
if (mLabel.getBold() && mLabel.getItalic())
|
||||
typeface = Typeface.BOLD_ITALIC;
|
||||
else {
|
||||
if (mLabel.getBold())
|
||||
typeface = Typeface.BOLD;
|
||||
else if (mLabel.getItalic())
|
||||
typeface = Typeface.ITALIC;
|
||||
}
|
||||
return typeface;
|
||||
}
|
||||
}
|
||||
|
||||
private class OutDrawer implements IDrawer {
|
||||
private Path mPath;
|
||||
private RectF mBoundsOutside;
|
||||
private float mMinSize, mX, mY;
|
||||
|
||||
private OutDrawer(float min) {
|
||||
mMinSize = min * 0.5f;
|
||||
mPaint.setAlpha(255);
|
||||
}
|
||||
|
||||
private void leftOut(RectF rect, float screenH) {
|
||||
mX = 0f;
|
||||
mY = Math.min(Math.max(mMinSize, rect.top + rect.height() * 0.5f), screenH - mMinSize);
|
||||
mPath = getLeftAlignedTriangle(mX, mY, mMinSize);
|
||||
mBoundsOutside = new RectF(mX, mY - mMinSize, mX + mMinSize, mY + mMinSize);
|
||||
}
|
||||
|
||||
private void topOut(RectF rect, float screenW) {
|
||||
mX = Math.min(Math.max(mMinSize, rect.left + rect.width() * 0.5f), screenW - mMinSize);
|
||||
mY = 0f;
|
||||
mPath = getTopAlignedTriangle(mX, mY, mMinSize);
|
||||
mBoundsOutside = new RectF(mX - mMinSize, mY, mX + mMinSize * 0.5f, mY + mMinSize);
|
||||
}
|
||||
|
||||
private void rightOut(RectF rect, float screenW, float screenH) {
|
||||
mX = screenW;
|
||||
mY = Math.min(Math.max(mMinSize, rect.top + rect.height() * 0.5f), screenH - mMinSize);
|
||||
mPath = getRightAlignedTriangle(mX, mY, mMinSize);
|
||||
mBoundsOutside = new RectF(mX - mMinSize, mY - mMinSize, mX, mY + mMinSize);
|
||||
}
|
||||
|
||||
private void bottomOut(RectF rect, float screenW, float screenH) {
|
||||
mX = Math.min(Math.max(mMinSize, rect.left + rect.width() * 0.5f), screenW - mMinSize);
|
||||
mY = screenH;
|
||||
mPath = getBottomAlignedTriangle(mX, mY, mMinSize);
|
||||
mBoundsOutside = new RectF(mX - mMinSize, mY - mMinSize, mX + mMinSize, mY);
|
||||
}
|
||||
|
||||
private Path getLeftAlignedTriangle(float x, float y, float r) {
|
||||
Path path = new Path();
|
||||
path.moveTo(x, y - r);
|
||||
path.lineTo(x, y + r);
|
||||
path.lineTo(x + r * 0.6f, y);
|
||||
path.lineTo(x, y - r);
|
||||
return path;
|
||||
}
|
||||
|
||||
private Path getTopAlignedTriangle(float x, float y, float r) {
|
||||
Path path = new Path();
|
||||
path.moveTo(x - r, y);
|
||||
path.lineTo(x, y + r * 0.6f);
|
||||
path.lineTo(x + r, y);
|
||||
path.lineTo(x - r, y);
|
||||
return path;
|
||||
}
|
||||
|
||||
private Path getRightAlignedTriangle(float x, float y, float r) {
|
||||
Path path = new Path();
|
||||
path.moveTo(x, y - r);
|
||||
path.lineTo(x - r * 0.6f, y);
|
||||
path.lineTo(x, y + r);
|
||||
path.lineTo(x, y - r);
|
||||
return path;
|
||||
}
|
||||
|
||||
private Path getBottomAlignedTriangle(float x, float y, float r) {
|
||||
Path path = new Path();
|
||||
path.moveTo(x - r, y);
|
||||
path.lineTo(x, y - r * 0.6f);
|
||||
path.lineTo(x + r, y);
|
||||
path.lineTo(x - r, y);
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
mPaint.setColor(mLabel.getForeColor());
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
|
||||
mPaint.setColor(Color.WHITE);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas, Rect src, Rect dst) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawShadow(Canvas canvas) {
|
||||
float r = 2f * mMinSize;
|
||||
|
||||
mPaint.setColor(Color.LTGRAY);
|
||||
mPaint.setAlpha(100);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
canvas.drawCircle(mX, mY, r, mPaint);
|
||||
|
||||
mPaint.setAlpha(255);
|
||||
mPaint.setStyle(Paint.Style.STROKE);
|
||||
|
||||
mPaint.setColor(Color.RED);
|
||||
canvas.drawCircle(mX, mY, r + 1f, mPaint);
|
||||
mPaint.setColor(Color.GREEN);
|
||||
canvas.drawCircle(mX, mY, r, mPaint);
|
||||
mPaint.setColor(Color.BLUE);
|
||||
canvas.drawCircle(mX, mY, r - 1f, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RectF getBounds() {
|
||||
return mBoundsOutside;
|
||||
}
|
||||
}
|
||||
|
||||
private final Paint mPaint;
|
||||
private Label mLabel;
|
||||
private IDrawer mDrawer;
|
||||
|
||||
LabelPainter(@NonNull Label label) {
|
||||
mLabel = label;
|
||||
mPaint = new Paint();
|
||||
mPaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
void draw(Canvas canvas) {
|
||||
mDrawer.draw(canvas);
|
||||
}
|
||||
|
||||
void drawActive(Canvas canvas) {
|
||||
mDrawer.drawShadow(canvas);
|
||||
mDrawer.draw(canvas);
|
||||
}
|
||||
|
||||
void draw(Canvas canvas, Rect src, Rect dst) {
|
||||
mDrawer.draw(canvas, src, dst);
|
||||
}
|
||||
|
||||
RectF getBounds() {
|
||||
return mDrawer.getBounds();
|
||||
}
|
||||
|
||||
void setLabel(@NonNull Label label) {
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
void update(float sizeFactor, float screenW, float screenH, float x, float y) {
|
||||
InDrawer inDrawer = new InDrawer(sizeFactor, x, y);
|
||||
|
||||
RectF rect = inDrawer.getBounds();
|
||||
float minSize = 1.5f * sizeFactor;
|
||||
|
||||
OutDrawer outDrawer = null;
|
||||
if (rect.right < minSize) { // left out
|
||||
outDrawer = new OutDrawer(minSize);
|
||||
outDrawer.leftOut(rect, screenH);
|
||||
} else if (rect.bottom < minSize) {// top out
|
||||
outDrawer = new OutDrawer(minSize);
|
||||
outDrawer.topOut(rect, screenW);
|
||||
} else if (rect.left > (screenW - minSize)) { // right out
|
||||
outDrawer = new OutDrawer(minSize);
|
||||
outDrawer.rightOut(rect, screenW, screenH);
|
||||
} else if (rect.top > (screenH - minSize)) { // bottom out
|
||||
outDrawer = new OutDrawer(minSize);
|
||||
outDrawer.bottomOut(rect, screenW, screenH);
|
||||
}
|
||||
|
||||
mDrawer = outDrawer == null ? inDrawer : outDrawer;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue