Advertisement
woodenwaffles

surfaceview

Jan 10th, 2018
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.46 KB | None | 0 0
  1. class TextMessage extends SurfaceView implements SurfaceHolder.Callback {
  2. private SurfaceHolder surfaceHolder;
  3. private int padding = 32; // For one side
  4. private int radius = 25;
  5. private int textsize = 30;
  6. private int typelinegap = (int)(8 * getContext().getResources().getDisplayMetrics().density);
  7. private int viewWidth;
  8. private int viewHeight;
  9. private int maxTextWidth;
  10. private int textColor = Color.WHITE;
  11. private int windowColor;
  12. private String message;
  13. private Integer boxColor = Color.BLUE;
  14. private String platform = "samsung";
  15. private Paint paint;
  16.  
  17. public TextMessage(Context context, AttributeSet attrs) {
  18. super(context, attrs);
  19. TypedArray a = context.getTheme().obtainStyledAttributes(
  20. attrs,
  21. R.styleable.TextMessage,
  22. 0, 0);
  23.  
  24. try {
  25. textColor = a.getColor(R.styleable.TextMessage_textColor, Color.WHITE);
  26. boxColor = a.getColor(R.styleable.TextMessage_msgBoxColor, Integer.MIN_VALUE);
  27. boxColor = (boxColor.intValue() == Integer.MIN_VALUE) ? null : boxColor;
  28. textsize = a.getDimensionPixelSize(R.styleable.TextMessage_textSize, 30);
  29. platform = a.getString(R.styleable.TextMessage_platform).toLowerCase();
  30. message = a.getString(R.styleable.TextMessage_text);
  31. message = (message == null) ? "\uD83D\uDE01\uD83D\uDE01\uD83D\uDE01\uD83D\uDE01\uD83D\uDE01" : message;
  32. init();
  33. }
  34. finally {
  35. a.recycle();
  36. }
  37. }
  38.  
  39. public TextMessage(Context context, String message, int viewWidth, String platform, int textColor,
  40. Integer boxColor, int textsize) {
  41. super(context);
  42. this.message = message;
  43. this.viewWidth = viewWidth;
  44. this.platform = platform;
  45. this.textColor = textColor;
  46. this.boxColor = boxColor;
  47. this.textsize = textsize;
  48. init();
  49. }
  50.  
  51. private void init() {
  52. paint = new Paint();
  53. this.setWillNotDraw(false);
  54. this.setZOrderMediaOverlay(true);
  55. surfaceHolder = getHolder();
  56. surfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
  57. surfaceHolder.addCallback(this);
  58.  
  59. TypedArray array = getContext().obtainStyledAttributes(new int[] {
  60. android.R.attr.colorBackground,
  61. android.R.attr.textColorPrimary,
  62. });
  63. try {
  64. windowColor = array.getColor(0, 0xFF00FF);
  65. }
  66. finally {
  67. array.recycle();
  68. }
  69. }
  70.  
  71. @Override
  72. public void surfaceCreated(SurfaceHolder surfaceHolder) {
  73. new DrawTextTask().execute(this);
  74. }
  75.  
  76. @Override
  77. public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
  78. // TODO
  79. }
  80.  
  81. @Override
  82. public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
  83. // TODO
  84. }
  85.  
  86. @Override
  87. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  88. viewWidth = MeasureSpec.getSize(widthMeasureSpec);
  89. this.maxTextWidth = viewWidth - (2 * (padding + radius));
  90. setMeasuredDimension(viewWidth, measureViewHeight());
  91. }
  92.  
  93. // Reduced copied code, used in determining message Height and actually drawing the text
  94. public int formatMessage(@Nullable Canvas canvas) {
  95. int line = 1;
  96. boolean draw = canvas != null;
  97. paint.setColor(textColor);
  98. paint.setTextSize(textsize);
  99. StringBuilder stringBuilder = new StringBuilder("");
  100. String[] words = message.split(" ");
  101. Log.d("Emoji", "Words:" + words.length);
  102. for (int n = 0; n < words.length; n++) {
  103. if (stringBuilder.length() != 0)
  104. stringBuilder.append(" ");
  105. stringBuilder.append(words[n]);
  106. if (paint.measureText(stringBuilder.toString()) > maxTextWidth) {
  107. if ((paint.measureText(words[n]) / (double) maxTextWidth) > 0.25) {
  108. int x = stringBuilder.length() - 1;
  109. char c = stringBuilder.charAt(x);
  110. if ((c >= 55296 && c <= 56319) || (c >= 56320 && c <= 57343))
  111. x--;
  112. while(paint.measureText(stringBuilder.substring(0, x)) > maxTextWidth) {
  113. x--;
  114. char ch = stringBuilder.charAt(x);
  115. if ((ch >= 55296 && ch <= 56319) || (ch >= 56320 && ch <= 57343))
  116. x--;
  117. }
  118. String halfWord = stringBuilder.substring(x);
  119. ArrayList<String> breakWords = new ArrayList<>();
  120. int b = 0;
  121. for (int a = 1; a <= halfWord.length(); a++) {
  122. char ch = stringBuilder.charAt(a);
  123. if ((ch >= 55296 && ch <= 56319) || (ch >= 56320 && ch <= 57343))
  124. a++;
  125. String substring = halfWord.substring(b, a);
  126. if (paint.measureText(substring) > maxTextWidth) {
  127. breakWords.add(substring);
  128. b = a;
  129. }
  130. }
  131. breakWords.add(halfWord.substring(b));
  132.  
  133. if (draw)
  134. writeText(canvas, stringBuilder.substring(0, x), line);
  135. line += 1;
  136. stringBuilder.delete(0, stringBuilder.length());
  137.  
  138. for (int a = 0; a < breakWords.size() - 1; a++) {
  139. if (draw)
  140. writeText(canvas, breakWords.get(a), line);
  141. line += 1;
  142. }
  143. stringBuilder.append(breakWords.get(breakWords.size() - 1));
  144. } else {
  145. stringBuilder.delete(stringBuilder.length() - words[n].length(), stringBuilder.length());
  146. if (draw)
  147. writeText(canvas, stringBuilder.toString(), line);
  148. line += 1;
  149. n--;
  150. stringBuilder.delete(0, stringBuilder.length());
  151. }
  152. }
  153. }
  154. if (draw)
  155. writeText(canvas, stringBuilder.toString(), line);
  156. return line;
  157. }
  158.  
  159. private void writeText(Canvas canvas, String msg, final int line) {
  160. int b = 0, offsetX = 0;
  161. for (int x = 0; x < msg.length(); x++) {
  162. final char c = msg.charAt(x);
  163. if (c >= 55296 && c <= 56319) {
  164. final char nextC = msg.charAt(x + 1);
  165. if (nextC >= 56320 && nextC <= 57343) {
  166. canvas.drawText(msg.substring(b, x), padding + radius + offsetX, (line * textsize) + ((line - 1) *
  167. ((line > 1) ? typelinegap : 0)) + padding + radius, paint);
  168. offsetX += paint.measureText(msg.substring(b, x));
  169.  
  170. final int currentOffsetX = offsetX;
  171. String emojiCode = Integer.toHexString(Character.toCodePoint(c, nextC));
  172. Bitmap emoji = getBitmapFromURL("https://raw.githubusercontent.com/" +
  173. "myrepository/master/" + emojiCode + "-" + platform + ".png");
  174. final double heightMultiplier = 1.5;
  175. int emojiWidth = ((int) ((((double)emoji.getWidth()) / emoji.getHeight()) * textsize * heightMultiplier));
  176. int emojiHeightIncrease = (int) ((textsize * (heightMultiplier - 1)) / 2);
  177. Rect emojiRectangle = new Rect(padding + radius + currentOffsetX, (line * textsize) + ((line - 1) *
  178. ((line > 1) ? typelinegap : 0)) + padding + radius - textsize - emojiHeightIncrease,
  179. padding + radius + currentOffsetX + emojiWidth,
  180. (line * textsize) + ((line - 1) *
  181. ((line > 1) ? typelinegap : 0)) + padding + radius + emojiHeightIncrease);
  182. canvas.drawBitmap(emoji, null, emojiRectangle, paint);
  183.  
  184. offsetX += emojiWidth;
  185. b = x + 2;
  186. x++;
  187. }
  188. }
  189. }
  190. canvas.drawText(msg.substring(b), padding + radius + offsetX, (line * textsize) + ((line - 1) *
  191. ((line > 1) ? typelinegap : 0)) + padding + radius, paint);
  192. }
  193.  
  194. private void drawBox(Canvas canvas) {
  195. paint.setColor(boxColor);
  196. Path p = new Path();
  197. p.moveTo(padding + radius, padding + radius);
  198. for (int n = 180; n <= 270; n++)
  199. p.lineTo(padding + radius + (float) (radius * Math.cos(Math.toRadians(n))),
  200. padding + radius + (float) (radius * Math.sin(Math.toRadians(n))));
  201. p.rLineTo(viewWidth - padding - radius, 0);
  202. for (int n = 270; n <= 360; n++)
  203. p.lineTo(viewWidth - padding - radius + (float) (radius * Math.cos(Math.toRadians(n))),
  204. padding + radius + (float) (radius * Math.sin(Math.toRadians(n))));
  205. p.lineTo(viewWidth - padding, viewHeight - padding);
  206. p.lineTo(padding + radius, viewHeight - padding);
  207. for (int n = 90; n <= 180; n++)
  208. p.lineTo(padding + radius + (float) (radius * Math.cos(Math.toRadians(n))),
  209. viewHeight - radius - padding + (float) (radius * Math.sin(Math.toRadians(n))));
  210. p.lineTo(padding, radius + padding);
  211. canvas.drawPath(p, paint);
  212. }
  213.  
  214. public void setMessage(String message) {
  215. this.message = message;
  216. requestLayout();
  217. new DrawTextTask().execute(this);
  218. }
  219.  
  220. protected int measureViewHeight() {
  221. int line = formatMessage(null);
  222. this.viewHeight = (textsize * line) + (2 * (radius + padding)) + (typelinegap * line - 1);
  223. return viewHeight;
  224. }
  225.  
  226. public void doDraw(Canvas canvas) {
  227. Bitmap canvasBitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
  228. Canvas c = new Canvas(canvasBitmap);
  229. c.drawColor(windowColor);
  230.  
  231. if (boxColor != null)
  232. drawBox(c);
  233.  
  234. formatMessage(c);
  235.  
  236. canvas.drawBitmap(canvasBitmap, 0,0, null);
  237. }
  238.  
  239. public static Bitmap getBitmapFromURL(String src) {
  240. try {
  241. URL url = new URL(src);
  242. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  243. connection.setDoInput(true);
  244. connection.connect();
  245. InputStream input = connection.getInputStream();
  246. Bitmap myBitmap = BitmapFactory.decodeStream(input);
  247. return myBitmap;
  248. } catch (MalformedURLException e) {
  249. e.printStackTrace();
  250. } catch (IOException e) {
  251. e.printStackTrace();
  252. }
  253. return null;
  254. }
  255. }
  256.  
  257. class DrawTextTask extends AsyncTask<TextMessage, Void, Void> {
  258. @Override
  259. protected Void doInBackground(TextMessage[] param) {
  260. TextMessage msg = param[0];
  261. SurfaceHolder holder = msg.getHolder();
  262.  
  263. Canvas c = null;
  264. try {
  265. c = holder.lockCanvas();
  266. synchronized (holder) {
  267. Log.d("Emoji", "Doing draw");
  268. msg.doDraw(c);
  269. }
  270. } finally {
  271. if (c != null) {
  272. holder.unlockCanvasAndPost(c);
  273. }
  274. }
  275. return null;
  276. }
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement