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"?>
|
||||
<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_descr">Show rendering performance data for debugging purposes</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"/>
|
||||
<CheckBoxPreference android:summary="@string/continuous_rendering_descr" android:title="@string/continuous_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: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 StringPreference(String id, String defaultValue, boolean global) {
|
||||
|
@ -373,6 +396,10 @@ public class OsmandSettings {
|
|||
public final OsmandPreference<Boolean> USE_HIGH_RES_MAPS =
|
||||
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
|
||||
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);
|
||||
|
||||
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;
|
||||
endZoom = 18;
|
||||
entries = new String[endZoom - startZoom + 1];
|
||||
|
|
|
@ -385,6 +385,7 @@ public class MapRenderRepositories {
|
|||
currentRenderingContext.height = (int) (requestedBox.getTileHeight() * OsmandRenderer.TILE_SIZE);
|
||||
currentRenderingContext.nightMode = nightMode;
|
||||
currentRenderingContext.highResMode = prefs.USE_HIGH_RES_MAPS.get();
|
||||
currentRenderingContext.mapTextSize = prefs.MAP_TEXT_SIZE.get();
|
||||
if (checkWhetherInterrupted()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@ public class OsmandRenderer {
|
|||
public boolean interrupted = false;
|
||||
public boolean nightMode = false;
|
||||
public boolean highResMode = false;
|
||||
public float mapTextSize = 1;
|
||||
|
||||
List<TextDrawInfo> textToDraw = new ArrayList<TextDrawInfo>();
|
||||
List<IconDrawInfo> iconsToDraw = new ArrayList<IconDrawInfo>();
|
||||
|
@ -153,6 +154,7 @@ public class OsmandRenderer {
|
|||
RenderingPaintProperties[] adds = null;
|
||||
|
||||
|
||||
|
||||
public void clearText() {
|
||||
showAnotherText = null;
|
||||
showTextOnPath = false;
|
||||
|
@ -226,6 +228,7 @@ public class OsmandRenderer {
|
|||
|
||||
paintText = new TextPaint();
|
||||
paintText.setStyle(Style.FILL);
|
||||
paintText.setStrokeWidth(1);
|
||||
paintText.setColor(Color.BLACK);
|
||||
paintText.setTextAlign(Align.CENTER);
|
||||
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) {
|
||||
if (rc.highResMode) {
|
||||
return val * dm.density;
|
||||
return val * dm.density * rc.mapTextSize;
|
||||
} 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++) {
|
||||
TextDrawInfo text = rc.textToDraw.get(i);
|
||||
|
@ -447,27 +447,127 @@ public class OsmandRenderer {
|
|||
if(useEnglishNames){
|
||||
text.text = Junidecode.unidecode(text.text);
|
||||
}
|
||||
RectF bounds = new RectF();
|
||||
if(!rc.highResMode){
|
||||
paintText.setTextSize(getDensityValue(rc, text.textSize));
|
||||
} else {
|
||||
paintText.setTextSize(text.textSize);
|
||||
}
|
||||
|
||||
|
||||
// sest text size before finding intersection (it is used there)
|
||||
float textSize = getDensityValue(rc, text.textSize);
|
||||
paintText.setTextSize(textSize);
|
||||
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);
|
||||
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.
|
||||
int ascent = (int) Math.ceil(-paintText.ascent());
|
||||
int descent = (int) Math.ceil(paintText.descent());
|
||||
float textHeight = ascent + descent + (horizontalWayDisplay ? 0 : text.minDistance) + getDensityValue(rc, 5);
|
||||
|
||||
|
||||
RectF bounds = new RectF();
|
||||
if(text.drawOnPath == null || horizontalWayDisplay){
|
||||
bounds.set(text.centerX - mes / 2, text.centerY - textHeight / 2 ,
|
||||
text.centerX + mes / 2 , text.centerY + textHeight / 2 );
|
||||
bounds.set(text.centerX - textWidth / 2, text.centerY - textHeight / 2 ,
|
||||
text.centerX + textWidth / 2 , text.centerY + textHeight / 2 );
|
||||
} else {
|
||||
bounds.set(text.centerX - textHeight / 2, text.centerY - mes / 2,
|
||||
text.centerX + textHeight / 2 , text.centerY + mes / 2);
|
||||
bounds.set(text.centerX - textHeight / 2, text.centerY - textWidth / 2,
|
||||
text.centerX + textHeight / 2 , text.centerY + textWidth / 2);
|
||||
}
|
||||
List<RectF> boundsIntersect = text.drawOnPath == null || findAllTextIntersections?
|
||||
boundsNotPathIntersect : boundsPathIntersect;
|
||||
|
@ -513,7 +613,7 @@ public class OsmandRenderer {
|
|||
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);
|
||||
if ((x > diff && y > diff2) || (x > diff2 && y > diff)) {
|
||||
continue nextText;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// store in list sorted by left boundary
|
||||
|
@ -528,77 +628,7 @@ public class OsmandRenderer {
|
|||
// }
|
||||
boundsIntersect.add(index, bounds);
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue