Add text size property, improve text rendering
This commit is contained in:
parent
d8abd5beb9
commit
5d18bbd92e
7 changed files with 207 additions and 139 deletions
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="map_text_size_descr">Select text size for names on the map</string>
|
||||||
|
<string name="map_text_size">Text size</string>
|
||||||
<string name="trace_rendering">Rendering debug info</string>
|
<string name="trace_rendering">Rendering debug info</string>
|
||||||
<string name="trace_rendering_descr">Show rendering performance data for debugging purposes</string>
|
<string name="trace_rendering_descr">Show rendering performance data for debugging purposes</string>
|
||||||
<string name="tip_recent_changes">Recent changes</string>
|
<string name="tip_recent_changes">Recent changes</string>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
android:dialogMessage="@string/modify_transparency" android:title="@string/map_transparency" android:summary="@string/map_transparency_descr"/>
|
android:dialogMessage="@string/modify_transparency" android:title="@string/map_transparency" android:summary="@string/map_transparency_descr"/>
|
||||||
<CheckBoxPreference android:summary="@string/continuous_rendering_descr" android:title="@string/continuous_rendering"
|
<CheckBoxPreference android:summary="@string/continuous_rendering_descr" android:title="@string/continuous_rendering"
|
||||||
android:key="use_step_by_step_rendering" />
|
android:key="use_step_by_step_rendering" />
|
||||||
|
<ListPreference android:key="map_text_size" android:title="@string/map_text_size" android:summary="@string/map_text_size_descr"/>
|
||||||
<CheckBoxPreference android:key="use_high_res_maps" android:title="@string/use_high_res_maps" android:summary="@string/use_high_res_maps_descr"></CheckBoxPreference>
|
<CheckBoxPreference android:key="use_high_res_maps" android:title="@string/use_high_res_maps" android:summary="@string/use_high_res_maps_descr"></CheckBoxPreference>
|
||||||
|
|
||||||
<CheckBoxPreference android:summary="@string/trace_rendering_descr" android:title="@string/trace_rendering"
|
<CheckBoxPreference android:summary="@string/trace_rendering_descr" android:title="@string/trace_rendering"
|
||||||
|
|
|
@ -299,6 +299,29 @@ public class OsmandSettings {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class FloatPreference extends CommonPreference<Float> {
|
||||||
|
|
||||||
|
|
||||||
|
private FloatPreference(String id, float defaultValue, boolean global) {
|
||||||
|
super(id, global, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FloatPreference(String id, float defaultValue, boolean global, boolean cache) {
|
||||||
|
super(id, global, cache, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Float getValue(SharedPreferences prefs, Float defaultValue) {
|
||||||
|
return prefs.getFloat(getId(), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean setValue(SharedPreferences prefs, Float val) {
|
||||||
|
return prefs.edit().putFloat(getId(), val).commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private class StringPreference extends CommonPreference<String> {
|
private class StringPreference extends CommonPreference<String> {
|
||||||
|
|
||||||
private StringPreference(String id, String defaultValue, boolean global) {
|
private StringPreference(String id, String defaultValue, boolean global) {
|
||||||
|
@ -373,6 +396,10 @@ public class OsmandSettings {
|
||||||
public final OsmandPreference<Boolean> USE_HIGH_RES_MAPS =
|
public final OsmandPreference<Boolean> USE_HIGH_RES_MAPS =
|
||||||
new BooleanPreference("use_high_res_maps", false, false, true);
|
new BooleanPreference("use_high_res_maps", false, false, true);
|
||||||
|
|
||||||
|
// this value string is synchronized with settings_pref.xml preference name
|
||||||
|
public final OsmandPreference<Float> MAP_TEXT_SIZE =
|
||||||
|
new FloatPreference("map_text_size", 1.0f, false, true);
|
||||||
|
|
||||||
|
|
||||||
// this value string is synchronized with settings_pref.xml preference name
|
// this value string is synchronized with settings_pref.xml preference name
|
||||||
public final OsmandPreference<Boolean> SHOW_POI_OVER_MAP =
|
public final OsmandPreference<Boolean> SHOW_POI_OVER_MAP =
|
||||||
|
|
|
@ -226,6 +226,13 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
|
||||||
}
|
}
|
||||||
registerListPreference(osmandSettings.MAX_LEVEL_TO_DOWNLOAD_TILE, screen, entries, intValues);
|
registerListPreference(osmandSettings.MAX_LEVEL_TO_DOWNLOAD_TILE, screen, entries, intValues);
|
||||||
|
|
||||||
|
Float[] floatValues = new Float[] {0.3f, 0.5f, 0.7f, 0.8f, 1.0f, 1.2f, 1.3f, 1.5f, 2.0f, 2.5f};
|
||||||
|
entries = new String[floatValues.length];
|
||||||
|
for (int i = 0; i < floatValues.length; i++) {
|
||||||
|
entries[i] = floatValues[i] +"";
|
||||||
|
}
|
||||||
|
registerListPreference(osmandSettings.MAP_TEXT_SIZE, screen, entries, floatValues);
|
||||||
|
|
||||||
startZoom = 1;
|
startZoom = 1;
|
||||||
endZoom = 18;
|
endZoom = 18;
|
||||||
entries = new String[endZoom - startZoom + 1];
|
entries = new String[endZoom - startZoom + 1];
|
||||||
|
|
|
@ -385,6 +385,7 @@ public class MapRenderRepositories {
|
||||||
currentRenderingContext.height = (int) (requestedBox.getTileHeight() * OsmandRenderer.TILE_SIZE);
|
currentRenderingContext.height = (int) (requestedBox.getTileHeight() * OsmandRenderer.TILE_SIZE);
|
||||||
currentRenderingContext.nightMode = nightMode;
|
currentRenderingContext.nightMode = nightMode;
|
||||||
currentRenderingContext.highResMode = prefs.USE_HIGH_RES_MAPS.get();
|
currentRenderingContext.highResMode = prefs.USE_HIGH_RES_MAPS.get();
|
||||||
|
currentRenderingContext.mapTextSize = prefs.MAP_TEXT_SIZE.get();
|
||||||
if (checkWhetherInterrupted()) {
|
if (checkWhetherInterrupted()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,7 @@ public class OsmandRenderer {
|
||||||
public boolean interrupted = false;
|
public boolean interrupted = false;
|
||||||
public boolean nightMode = false;
|
public boolean nightMode = false;
|
||||||
public boolean highResMode = false;
|
public boolean highResMode = false;
|
||||||
|
public float mapTextSize = 1;
|
||||||
|
|
||||||
List<TextDrawInfo> textToDraw = new ArrayList<TextDrawInfo>();
|
List<TextDrawInfo> textToDraw = new ArrayList<TextDrawInfo>();
|
||||||
List<IconDrawInfo> iconsToDraw = new ArrayList<IconDrawInfo>();
|
List<IconDrawInfo> iconsToDraw = new ArrayList<IconDrawInfo>();
|
||||||
|
@ -153,6 +154,7 @@ public class OsmandRenderer {
|
||||||
RenderingPaintProperties[] adds = null;
|
RenderingPaintProperties[] adds = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void clearText() {
|
public void clearText() {
|
||||||
showAnotherText = null;
|
showAnotherText = null;
|
||||||
showTextOnPath = false;
|
showTextOnPath = false;
|
||||||
|
@ -226,6 +228,7 @@ public class OsmandRenderer {
|
||||||
|
|
||||||
paintText = new TextPaint();
|
paintText = new TextPaint();
|
||||||
paintText.setStyle(Style.FILL);
|
paintText.setStyle(Style.FILL);
|
||||||
|
paintText.setStrokeWidth(1);
|
||||||
paintText.setColor(Color.BLACK);
|
paintText.setColor(Color.BLACK);
|
||||||
paintText.setTextAlign(Align.CENTER);
|
paintText.setTextAlign(Align.CENTER);
|
||||||
paintText.setTypeface(Typeface.create("Droid Serif", Typeface.NORMAL)); //$NON-NLS-1$
|
paintText.setTypeface(Typeface.create("Droid Serif", Typeface.NORMAL)); //$NON-NLS-1$
|
||||||
|
@ -414,9 +417,9 @@ public class OsmandRenderer {
|
||||||
|
|
||||||
private float getDensityValue(RenderingContext rc, float val) {
|
private float getDensityValue(RenderingContext rc, float val) {
|
||||||
if (rc.highResMode) {
|
if (rc.highResMode) {
|
||||||
return val * dm.density;
|
return val * dm.density * rc.mapTextSize;
|
||||||
} else {
|
} else {
|
||||||
return val;
|
return val * rc.mapTextSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,9 +434,6 @@ public class OsmandRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
paint.setStyle(Style.STROKE);
|
|
||||||
paint.setTextSize(10);
|
|
||||||
paint.setColor(Color.BLACK);
|
|
||||||
|
|
||||||
nextText: for (int i = 0; i < size; i++) {
|
nextText: for (int i = 0; i < size; i++) {
|
||||||
TextDrawInfo text = rc.textToDraw.get(i);
|
TextDrawInfo text = rc.textToDraw.get(i);
|
||||||
|
@ -447,27 +447,127 @@ public class OsmandRenderer {
|
||||||
if(useEnglishNames){
|
if(useEnglishNames){
|
||||||
text.text = Junidecode.unidecode(text.text);
|
text.text = Junidecode.unidecode(text.text);
|
||||||
}
|
}
|
||||||
RectF bounds = new RectF();
|
|
||||||
if(!rc.highResMode){
|
|
||||||
paintText.setTextSize(getDensityValue(rc, text.textSize));
|
// sest text size before finding intersection (it is used there)
|
||||||
} else {
|
float textSize = getDensityValue(rc, text.textSize);
|
||||||
paintText.setTextSize(text.textSize);
|
paintText.setTextSize(textSize);
|
||||||
}
|
|
||||||
paintText.setFakeBoldText(text.bold);
|
paintText.setFakeBoldText(text.bold);
|
||||||
|
paintText.setColor(text.textColor);
|
||||||
|
// align center y
|
||||||
|
text.centerY += (-paintText.ascent());
|
||||||
|
|
||||||
|
// calculate if there is intersection
|
||||||
|
boolean intersects = findTextIntersection(rc, boundsNotPathIntersect, boundsPathIntersect, c, text);
|
||||||
|
if(intersects){
|
||||||
|
continue nextText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(text.drawOnPath != null){
|
||||||
|
if(text.textShadow > 0){
|
||||||
|
paintText.setColor(Color.WHITE);
|
||||||
|
paintText.setStyle(Style.STROKE);
|
||||||
|
paintText.setStrokeWidth(2 + text.textShadow);
|
||||||
|
cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText);
|
||||||
|
// reset
|
||||||
|
paintText.setStyle(Style.FILL);
|
||||||
|
paintText.setStrokeWidth(2);
|
||||||
|
paintText.setColor(text.textColor);
|
||||||
|
}
|
||||||
|
cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText);
|
||||||
|
} else {
|
||||||
|
if (text.shieldRes != 0) {
|
||||||
|
if (cachedIcons.get(text.shieldRes) == null) {
|
||||||
|
cachedIcons.put(text.shieldRes, BitmapFactory.decodeResource(context.getResources(), text.shieldRes));
|
||||||
|
}
|
||||||
|
Bitmap ico = cachedIcons.get(text.shieldRes);
|
||||||
|
if (ico != null) {
|
||||||
|
cv.drawBitmap(ico, text.centerX - ico.getWidth() / 2 - 0.5f, text.centerY
|
||||||
|
- ico.getHeight() / 2 - getDensityValue(rc, 4.5f)
|
||||||
|
, paintIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawWrappedText(cv, text, textSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawWrappedText(Canvas cv, TextDrawInfo text, float textSize) {
|
||||||
|
if(text.textWrap == 0){
|
||||||
|
// set maximum for all text
|
||||||
|
text.textWrap = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(text.text.length() > text.textWrap){
|
||||||
|
int start = 0;
|
||||||
|
int end = text.text.length();
|
||||||
|
int lastSpace = -1;
|
||||||
|
int line = 0;
|
||||||
|
int pos = 0;
|
||||||
|
int limit = 0;
|
||||||
|
while(pos < end){
|
||||||
|
lastSpace = -1;
|
||||||
|
limit += text.textWrap;
|
||||||
|
while(pos < limit && pos < end){
|
||||||
|
if(!Character.isLetterOrDigit(text.text.charAt(pos))){
|
||||||
|
lastSpace = pos;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
if(lastSpace == -1){
|
||||||
|
drawTextOnCanvas(cv, text.text.substring(start, pos),
|
||||||
|
text.centerX, text.centerY + line * (textSize + 2), paintText, text.textShadow);
|
||||||
|
start = pos;
|
||||||
|
} else {
|
||||||
|
drawTextOnCanvas(cv, text.text.substring(start, lastSpace),
|
||||||
|
text.centerX, text.centerY + line * (textSize + 2), paintText, text.textShadow);
|
||||||
|
start = lastSpace + 1;
|
||||||
|
limit += (start - pos) - 1;
|
||||||
|
}
|
||||||
|
line++;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
drawTextOnCanvas(cv, text.text, text.centerX, text.centerY, paintText, text.textShadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawTextOnCanvas(Canvas cv, String text, float centerX, float centerY, Paint paint, float textShadow){
|
||||||
|
if(textShadow > 0){
|
||||||
|
int c = paintText.getColor();
|
||||||
|
paintText.setStyle(Style.STROKE);
|
||||||
|
paintText.setColor(Color.WHITE);
|
||||||
|
paintText.setStrokeWidth(2 + textShadow);
|
||||||
|
cv.drawText(text, centerX, centerY, paint);
|
||||||
|
cv.drawText(text, centerX, centerY, paint);
|
||||||
|
// reset
|
||||||
|
paintText.setStrokeWidth(2);
|
||||||
|
paintText.setStyle(Style.FILL);
|
||||||
|
paintText.setColor(c);
|
||||||
|
}
|
||||||
|
cv.drawText(text, centerX, centerY, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean findTextIntersection(RenderingContext rc, List<RectF> boundsNotPathIntersect, List<RectF> boundsPathIntersect,
|
||||||
|
Comparator<RectF> c, TextDrawInfo text) {
|
||||||
boolean horizontalWayDisplay = (text.pathRotate > 45 && text.pathRotate < 135) || (text.pathRotate > 225 && text.pathRotate < 315);
|
boolean horizontalWayDisplay = (text.pathRotate > 45 && text.pathRotate < 135) || (text.pathRotate > 225 && text.pathRotate < 315);
|
||||||
float mes = paintText.measureText(text.text) + (!horizontalWayDisplay ? 0 : text.minDistance);
|
float textWidth = paintText.measureText(text.text) + (!horizontalWayDisplay ? 0 : text.minDistance);
|
||||||
// Paint.ascent is negative, so negate it.
|
// Paint.ascent is negative, so negate it.
|
||||||
int ascent = (int) Math.ceil(-paintText.ascent());
|
int ascent = (int) Math.ceil(-paintText.ascent());
|
||||||
int descent = (int) Math.ceil(paintText.descent());
|
int descent = (int) Math.ceil(paintText.descent());
|
||||||
float textHeight = ascent + descent + (horizontalWayDisplay ? 0 : text.minDistance) + getDensityValue(rc, 5);
|
float textHeight = ascent + descent + (horizontalWayDisplay ? 0 : text.minDistance) + getDensityValue(rc, 5);
|
||||||
|
|
||||||
|
RectF bounds = new RectF();
|
||||||
if(text.drawOnPath == null || horizontalWayDisplay){
|
if(text.drawOnPath == null || horizontalWayDisplay){
|
||||||
bounds.set(text.centerX - mes / 2, text.centerY - textHeight / 2 ,
|
bounds.set(text.centerX - textWidth / 2, text.centerY - textHeight / 2 ,
|
||||||
text.centerX + mes / 2 , text.centerY + textHeight / 2 );
|
text.centerX + textWidth / 2 , text.centerY + textHeight / 2 );
|
||||||
} else {
|
} else {
|
||||||
bounds.set(text.centerX - textHeight / 2, text.centerY - mes / 2,
|
bounds.set(text.centerX - textHeight / 2, text.centerY - textWidth / 2,
|
||||||
text.centerX + textHeight / 2 , text.centerY + mes / 2);
|
text.centerX + textHeight / 2 , text.centerY + textWidth / 2);
|
||||||
}
|
}
|
||||||
List<RectF> boundsIntersect = text.drawOnPath == null || findAllTextIntersections?
|
List<RectF> boundsIntersect = text.drawOnPath == null || findAllTextIntersections?
|
||||||
boundsNotPathIntersect : boundsPathIntersect;
|
boundsNotPathIntersect : boundsPathIntersect;
|
||||||
|
@ -513,7 +613,7 @@ public class OsmandRenderer {
|
||||||
float x = Math.min(bounds.right, b.right) - Math.max(b.left, bounds.left);
|
float x = Math.min(bounds.right, b.right) - Math.max(b.left, bounds.left);
|
||||||
float y = Math.min(bounds.bottom, b.bottom) - Math.max(b.top, bounds.top);
|
float y = Math.min(bounds.bottom, b.bottom) - Math.max(b.top, bounds.top);
|
||||||
if ((x > diff && y > diff2) || (x > diff2 && y > diff)) {
|
if ((x > diff && y > diff2) || (x > diff2 && y > diff)) {
|
||||||
continue nextText;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// store in list sorted by left boundary
|
// store in list sorted by left boundary
|
||||||
|
@ -528,77 +628,7 @@ public class OsmandRenderer {
|
||||||
// }
|
// }
|
||||||
boundsIntersect.add(index, bounds);
|
boundsIntersect.add(index, bounds);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
// Shadow layer
|
|
||||||
// paintText.setShadowLayer(text.textShadow, 0, 0, Color.WHITE);
|
|
||||||
// if(text.textShadow > 0){
|
|
||||||
// paintText.setColor(Color.WHITE);
|
|
||||||
// paintText.setTextSize(text.textSize + text.textShadow * 2);
|
|
||||||
// if(text.drawOnPath != null){
|
|
||||||
// cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText);
|
|
||||||
// } else {
|
|
||||||
// cv.drawText(text.text, text.centerX, text.centerY, paintText);
|
|
||||||
// }
|
|
||||||
// paintText.setTextSize(text.textSize);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
paintText.setColor(text.textColor);
|
|
||||||
if(text.drawOnPath != null){
|
|
||||||
cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText);
|
|
||||||
} else {
|
|
||||||
if(text.textWrap == 0){
|
|
||||||
// set maximum for all text
|
|
||||||
text.textWrap = 40;
|
|
||||||
}
|
|
||||||
if(text.shieldRes != 0){
|
|
||||||
if(cachedIcons.get(text.shieldRes) == null){
|
|
||||||
cachedIcons.put(text.shieldRes, BitmapFactory.decodeResource(context.getResources(), text.shieldRes));
|
|
||||||
}
|
|
||||||
Bitmap ico = cachedIcons.get(text.shieldRes);
|
|
||||||
if (ico != null) {
|
|
||||||
cv.drawBitmap(ico, text.centerX - ico.getWidth() / 2 - getDensityValue(rc, 0.5f),
|
|
||||||
text.centerY - text.textSize / 2 - getDensityValue(rc, 6.5f),
|
|
||||||
paintIcon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(text.text.length() > text.textWrap){
|
|
||||||
int start = 0;
|
|
||||||
int end = text.text.length();
|
|
||||||
int lastSpace = -1;
|
|
||||||
int line = 0;
|
|
||||||
int pos = 0;
|
|
||||||
int limit = 0;
|
|
||||||
while(pos < end){
|
|
||||||
lastSpace = -1;
|
|
||||||
limit += text.textWrap;
|
|
||||||
while(pos < limit && pos < end){
|
|
||||||
if(!Character.isLetterOrDigit(text.text.charAt(pos))){
|
|
||||||
lastSpace = pos;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
if(lastSpace == -1){
|
|
||||||
cv.drawText(text.text.substring(start, pos),
|
|
||||||
text.centerX, text.centerY + line * (text.textSize + 2), paintText);
|
|
||||||
start = pos;
|
|
||||||
} else {
|
|
||||||
cv.drawText(text.text.substring(start, lastSpace),
|
|
||||||
text.centerX, text.centerY + line * (text.textSize + 2), paintText);
|
|
||||||
start = lastSpace + 1;
|
|
||||||
limit += (start - pos) - 1;
|
|
||||||
}
|
|
||||||
line++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
cv.drawText(text.text, text.centerX, text.centerY, paintText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue