Dbrant has submitted this change and it was merged. Change subject: Additional tweaks/fixes for share-a-fact. ......................................................................
Additional tweaks/fixes for share-a-fact. - Fixed face offset. - Added dark gradient underneath text. - Tweaked some margins and offsets. - Put the share layout into a ScrollView, in case the display is too small for the generated image and buttons. - Hiding description when sharing from Main page. - Replaced registered-trademark character. - Fixed unrelated checkstyle. Bug: T86242 Change-Id: Ie3a89afcdc93844d82164836aef2b8632cdc992e --- M wikipedia/res/layout/dialog_share_preview.xml M wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java M wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java M wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java M wikipedia/src/main/java/org/wikipedia/page/snippet/ShareHandler.java M wikipedia/src/main/java/org/wikipedia/page/snippet/SnippetImage.java 6 files changed, 90 insertions(+), 34 deletions(-) Approvals: BearND: Looks good to me, approved Dbrant: Looks good to me, approved jenkins-bot: Verified diff --git a/wikipedia/res/layout/dialog_share_preview.xml b/wikipedia/res/layout/dialog_share_preview.xml index 0ff6530..4030b0f 100644 --- a/wikipedia/res/layout/dialog_share_preview.xml +++ b/wikipedia/res/layout/dialog_share_preview.xml @@ -1,11 +1,15 @@ <?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:background="@color/white_progressive_dark"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="0dp" - android:background="@color/white_progressive_dark" android:orientation="vertical"> <ImageView @@ -14,8 +18,9 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal|center_vertical" android:layout_marginTop="16dp" + android:layout_marginBottom="16dp" android:scaleType="centerInside" - android:src="@drawable/empty_nearby" + android:src="?attr/lead_image_drawable" android:background="@android:color/black" android:contentDescription="@string/snippet_share_preview_image_desc" /> @@ -31,4 +36,5 @@ android:layout_gravity="center_horizontal" android:text="@string/share_normal_button" /> -</LinearLayout> \ No newline at end of file +</LinearLayout> +</ScrollView> \ No newline at end of file diff --git a/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java b/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java index 8d4e4bb..ddd9e07 100644 --- a/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java +++ b/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java @@ -46,7 +46,6 @@ import org.wikipedia.login.User; import org.wikipedia.page.LinkMovementMethodExt; import org.wikipedia.page.PageProperties; -import org.wikipedia.settings.SettingsActivity; public class EditSectionActivity extends ThemedActionBarActivity { public static final String ACTION_EDIT_SECTION = "org.wikipedia.edit_section"; diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java index a76f839..f0c2bbb 100644 --- a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java +++ b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java @@ -444,8 +444,13 @@ return leadImagesHandler.getLeadImageBitmap(); } - public int getImageBaseYOffset() { - return leadImagesHandler.getImageBaseYOffset(); + /** + * Returns the normalized (0.0 to 1.0) vertical focus position of the lead image. + * A value of 0.0 represents the top of the image, and 1.0 represents the bottom. + * @return Normalized vertical focus position. + */ + public float getLeadImageFocusY() { + return leadImagesHandler.getLeadImageFocusY(); } /** diff --git a/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java b/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java index 62c3347..0a2c2ed 100644 --- a/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java +++ b/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java @@ -100,6 +100,7 @@ private int displayHeight; private int imageBaseYOffset = 0; + private float faceYOffsetNormalized = 0f; private float displayDensity; public interface OnLeadImageLayoutListener { @@ -191,7 +192,7 @@ } public Bitmap getLeadImageBitmap() { - return getBitmapFromView(image1); + return leadImagesEnabled ? getBitmapFromView(image1) : null; } // ideas from: @@ -215,8 +216,15 @@ return returnedBitmap; } - public int getImageBaseYOffset() { - return imageBaseYOffset; + /** + * Returns the normalized (0.0 to 1.0) vertical focus position of the lead image. + * A value of 0.0 represents the top of the image, and 1.0 represents the bottom. + * The "focus position" is currently defined by automatic face detection, but may be + * defined by other factors in the future. + * @return Normalized vertical focus position. + */ + public float getLeadImageFocusY() { + return faceYOffsetNormalized; } @Override @@ -239,14 +247,17 @@ int faceY = (int)(faceLocation.y * scale); // if we have a face, then offset to the face location imageBaseYOffset = -(faceY - (imagePlaceholder.getHeight() / 2)); - // give it a slight artificial boost, so that it appears slightly - // above the page title... + // Adjust the face position by a slight amount. + // The face recognizer gives the location of the *eyes*, whereas we actually + // want to center on the *nose*... final int faceBoost = 24; imageBaseYOffset -= (faceBoost * displayDensity); + faceYOffsetNormalized = faceLocation.y / bmpHeight; } else { // No face, so we'll just chop the top 25% off rather than centering - final int offsetDenom = 4; - imageBaseYOffset = -(newHeight - imagePlaceholder.getHeight()) / offsetDenom; + final float oneQuarter = 0.25f; + imageBaseYOffset = -(int)((newHeight - imagePlaceholder.getHeight()) * oneQuarter); + faceYOffsetNormalized = oneQuarter; } // is the offset too far to the top? if (imageBaseYOffset > 0) { diff --git a/wikipedia/src/main/java/org/wikipedia/page/snippet/ShareHandler.java b/wikipedia/src/main/java/org/wikipedia/page/snippet/ShareHandler.java index 23f89dd..bed9447 100644 --- a/wikipedia/src/main/java/org/wikipedia/page/snippet/ShareHandler.java +++ b/wikipedia/src/main/java/org/wikipedia/page/snippet/ShareHandler.java @@ -39,9 +39,9 @@ title.getCanonicalUri() + "?source=app"); Bitmap resultBitmap = new SnippetImage(activity, curPageFragment.getLeadImageBitmap(), - curPageFragment.getImageBaseYOffset(), + curPageFragment.getLeadImageFocusY(), title.getDisplayText(), - title.getDescription(), + curPageFragment.getPage().getPageProperties().isMainPage() ? "" : title.getDescription(), selectedText).createImage(); if (preferUrl) { new PreviewDialog(activity, resultBitmap, title.getDisplayText(), introText, diff --git a/wikipedia/src/main/java/org/wikipedia/page/snippet/SnippetImage.java b/wikipedia/src/main/java/org/wikipedia/page/snippet/SnippetImage.java index 38b3ff2..f7c8597 100644 --- a/wikipedia/src/main/java/org/wikipedia/page/snippet/SnippetImage.java +++ b/wikipedia/src/main/java/org/wikipedia/page/snippet/SnippetImage.java @@ -4,9 +4,13 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.LinearGradient; import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Shader; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.os.Build; import android.text.Html; import android.text.Layout; import android.text.Spanned; @@ -31,18 +35,18 @@ private final Context context; private final Bitmap leadImageBitmap; - private final int faceYOffset; + private final float leadImageFocusY; private final String title; private final String description; private final CharSequence textSnippet; private boolean isArticleRTL; public SnippetImage(Context context, Bitmap leadImageBitmap, - int faceYOffset, String title, String description, + float leadImageFocusY, String title, String description, CharSequence textSnippet) { this.context = context; this.leadImageBitmap = leadImageBitmap; - this.faceYOffset = faceYOffset; + this.leadImageFocusY = leadImageFocusY; this.title = title; this.description = description; this.textSnippet = textSnippet; @@ -54,39 +58,50 @@ * just use a black background. */ public Bitmap createImage() { - Bitmap resultBitmap = drawBackground(leadImageBitmap, faceYOffset); + Bitmap resultBitmap = drawBackground(leadImageBitmap, leadImageFocusY); Canvas canvas = new Canvas(resultBitmap); + if (leadImageBitmap != null) { + drawGradient(canvas); + } Layout textLayout = drawTextSnippet(canvas, textSnippet); isArticleRTL = textLayout.getParagraphDirection(0) == Layout.DIR_RIGHT_TO_LEFT; int top = drawLicenseIcons(canvas, context); - if (!TextUtils.isEmpty(description)) { - top = drawDescription(canvas, description, top); - } + top = drawDescription(canvas, description, top); drawTitle(canvas, title, top); - drawWordmark(canvas, context); return resultBitmap; } - private Bitmap drawBackground(Bitmap leadImageBitmap, int faceYOffset) { + private Bitmap drawBackground(Bitmap leadImageBitmap, float leadImageFocusY) { Bitmap resultBitmap; if (leadImageBitmap != null) { // use lead image - resultBitmap = scaleCropToFitFace(leadImageBitmap, WIDTH, HEIGHT, faceYOffset); + resultBitmap = scaleCropToFitFace(leadImageBitmap, WIDTH, HEIGHT, leadImageFocusY); } else { resultBitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); - // final int backgroundColor = Color.parseColor("#242438"); - final int backgroundColor = -14408648; + final int backgroundColor = 0xff242438; resultBitmap.eraseColor(backgroundColor); } return resultBitmap; } + private void drawGradient(Canvas canvas) { + // draw a dark gradient over the image, so that the white text + // will stand out better against it. + final int gradientStartColor = 0x20000000; + final int gradientStopColor = 0x60000000; + Shader shader = new LinearGradient(0, 0, 0, canvas.getHeight(), gradientStartColor, + gradientStopColor, Shader.TileMode.CLAMP); + Paint paint = new Paint(); + paint.setShader(shader); + canvas.drawRect(new Rect(0, 0, canvas.getWidth(), canvas.getHeight()), paint); + } + private Layout drawTextSnippet(Canvas canvas, CharSequence textSnippet) { - final int top = 5; + final int top = 16; final int maxHeight = 200; final int maxLines = 5; final float maxFontSize = 96.0f; @@ -118,6 +133,9 @@ final float maxFontSize = 15.0f; final float minFontSize = 10.0f; + if (TextUtils.isEmpty(description)) { + return top - marginBottom; + } TextPaint textPaint = new TextPaint(); textPaint.setAntiAlias(true); textPaint.setColor(Color.WHITE); @@ -143,7 +161,7 @@ } private void drawTitle(Canvas canvas, String title, int top) { - final int marginBottom = 1; + final int marginBottom = 0; final int maxHeight = 70; final int maxLines = 2; final float maxFontSize = 30.0f; @@ -164,8 +182,15 @@ if (isArticleRTL) { left = WIDTH - HORIZONTAL_PADDING - textLayout.getWidth(); } + int marginBottomTotal = marginBottom; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + // versions < 5.0 don't compensate for bottom margin correctly when line + // spacing is less than 1.0, so we'll compensate ourselves + final int marginBoost = 10; + marginBottomTotal += marginBoost; + } - top = top - marginBottom - textLayout.getHeight(); + top = top - marginBottomTotal - textLayout.getHeight(); canvas.save(); canvas.translate(left, top); textLayout.draw(canvas); @@ -213,7 +238,7 @@ final int rMaxWidth = (int) rFontSize; TextPaint rPaint = new TextPaint(textPaint); rPaint.setTextSize(rFontSize); - StaticLayout rLayout = buildLayout(new TextLayoutParams("\u24C7", rPaint, rMaxWidth, 1.0f)); + StaticLayout rLayout = buildLayout(new TextLayoutParams("\u00AE", rPaint, rMaxWidth, 1.0f)); final int rWidth = (int) rLayout.getLineWidth(0); int left = WIDTH - HORIZONTAL_PADDING - wordMarkWidth - rWidth; @@ -320,7 +345,7 @@ // Borrowed from http://stackoverflow.com/questions/5226922/crop-to-fit-image-in-android // Modified to allow for face detection adjustment, startY private Bitmap scaleCropToFitFace(Bitmap original, int targetWidth, int targetHeight, - int yOffset) { + float normalizedYOffset) { // Need to scale the image, keeping the aspect ratio first int width = original.getWidth(); int height = original.getHeight(); @@ -337,12 +362,22 @@ scaledWidth = targetWidth; scaledHeight = height * widthScale; // crop height by... -// startY = (int) ((scaledHeight - targetHeight) / 2); + startY = (int) (normalizedYOffset * scaledHeight - targetHeight / 2); + // Adjust the face position by a slight amount. + // The face recognizer gives the location of the *eyes*, whereas we actually + // want to center on the *nose*... + final int faceBoost = 32; + startY += faceBoost; + if (startY < 0) { + startY = 0; + } else if (startY + targetHeight > scaledHeight) { + startY = (int)(scaledHeight - targetHeight); + } } else { scaledHeight = targetHeight; scaledWidth = width * heightScale; // crop width by.. -// startX = (int) ((scaledWidth - targetWidth) / 2); + // startX = (int) ((scaledWidth - targetWidth) / 2); } Bitmap scaledBitmap -- To view, visit https://gerrit.wikimedia.org/r/191430 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie3a89afcdc93844d82164836aef2b8632cdc992e Gerrit-PatchSet: 5 Gerrit-Project: apps/android/wikipedia Gerrit-Branch: master Gerrit-Owner: Dbrant <[email protected]> Gerrit-Reviewer: BearND <[email protected]> Gerrit-Reviewer: Dbrant <[email protected]> Gerrit-Reviewer: Dr0ptp4kt <[email protected]> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
