/** Resets the dirty region when the motion event occurs. */
  private void resetDirtyRect(float eventX, float eventY) {

    // The lastTouchX and lastTouchY were set when the ACTION_DOWN
    // motion event occurred.
    dirtyRect.left = Math.min(lastTouchX, eventX);
    dirtyRect.right = Math.max(lastTouchX, eventX);
    dirtyRect.top = Math.min(lastTouchY, eventY);
    dirtyRect.bottom = Math.max(lastTouchY, eventY);
  }
예제 #2
0
  // ==============================================================================
  public final int[] renderGlyph(
      char glyph, Paint paint, android.graphics.Matrix matrix, Rect bounds) {
    Path p = new Path();
    paint.getTextPath(String.valueOf(glyph), 0, 1, 0.0f, 0.0f, p);

    RectF boundsF = new RectF();
    p.computeBounds(boundsF, true);
    matrix.mapRect(boundsF);

    boundsF.roundOut(bounds);
    bounds.left--;
    bounds.right++;

    final int w = bounds.width();
    final int h = Math.max(1, bounds.height());

    Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

    Canvas c = new Canvas(bm);
    matrix.postTranslate(-bounds.left, -bounds.top);
    c.setMatrix(matrix);
    c.drawPath(p, paint);

    final int sizeNeeded = w * h;
    if (cachedRenderArray.length < sizeNeeded) cachedRenderArray = new int[sizeNeeded];

    bm.getPixels(cachedRenderArray, 0, w, 0, 0, w, h);
    bm.recycle();
    return cachedRenderArray;
  }
 private int scrollBounds(int desiredScroll, int firstCell, int sizes[], int viewSize) {
   if (desiredScroll == 0) {
     // no op
   } else if (desiredScroll < 0) {
     desiredScroll = Math.max(desiredScroll, -sumArray(sizes, 1, firstCell));
   } else {
     desiredScroll =
         Math.min(
             desiredScroll,
             Math.max(
                 0,
                 sumArray(sizes, firstCell + 1, sizes.length - 1 - firstCell)
                     + sizes[0]
                     - viewSize));
   }
   return desiredScroll;
 }
예제 #4
0
 @Override
 public boolean getPadding(Rect padding) {
   padding.left = 0;
   padding.top = 0;
   padding.right = 0;
   padding.bottom = 0;
   final Rec[] array = mLayerState.mArray;
   final int N = mLayerState.mNum;
   for (int i = 0; i < N; i++) {
     reapplyPadding(i, array[i]);
     padding.left = Math.max(padding.left, mPaddingL[i]);
     padding.top = Math.max(padding.top, mPaddingT[i]);
     padding.right = Math.max(padding.right, mPaddingR[i]);
     padding.bottom = Math.max(padding.bottom, mPaddingB[i]);
   }
   return true;
 }
예제 #5
0
  // Grows the cropping rectange by (dx, dy) in image space.
  void moveBy(float dx, float dy) {

    Rect invalRect = new Rect(mDrawRect);

    mCropRect.offset(dx, dy);

    // Put the cropping rectangle inside image rectangle.
    mCropRect.offset(
        Math.max(0, mImageRect.left - mCropRect.left), Math.max(0, mImageRect.top - mCropRect.top));

    mCropRect.offset(
        Math.min(0, mImageRect.right - mCropRect.right),
        Math.min(0, mImageRect.bottom - mCropRect.bottom));

    mDrawRect = computeLayout();
    invalRect.union(mDrawRect);
    invalRect.inset(-10, -10);
    mContext.invalidate(invalRect);
  }
예제 #6
0
  // Audio
  public static void audioInit(
      int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
    int channelConfig =
        isStereo
            ? AudioFormat.CHANNEL_CONFIGURATION_STEREO
            : AudioFormat.CHANNEL_CONFIGURATION_MONO;
    int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
    int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);

    Log.v(
        "SDL",
        "SDL audio: wanted "
            + (isStereo ? "stereo" : "mono")
            + " "
            + (is16Bit ? "16-bit" : "8-bit")
            + " "
            + (sampleRate / 1000f)
            + "kHz, "
            + desiredFrames
            + " frames buffer");

    // Let the user pick a larger buffer if they really want -- but ye
    // gods they probably shouldn't, the minimums are horrifyingly high
    // latency already
    desiredFrames =
        Math.max(
            desiredFrames,
            (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1)
                / frameSize);

    mAudioTrack =
        new AudioTrack(
            AudioManager.STREAM_MUSIC,
            sampleRate,
            channelConfig,
            audioFormat,
            desiredFrames * frameSize,
            AudioTrack.MODE_STREAM);

    audioStartThread();

    Log.v(
        "SDL",
        "SDL audio: got "
            + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono")
            + " "
            + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT)
                ? "16-bit"
                : "8-bit")
            + " "
            + (mAudioTrack.getSampleRate() / 1000f)
            + "kHz, "
            + desiredFrames
            + " frames buffer");
  }
 /**
  * @param velocity
  * @return the page you should "land" on
  */
 private int getNextPage(int velocity) {
   int nextPage;
   if (velocity > mMinimumVelocity) {
     nextPage = getCurrentPageFloor();
   } else if (velocity < -mMinimumVelocity) {
     nextPage = getCurrentPageCeil();
   } else {
     nextPage = getCurrentPageRound();
   }
   return Math.min(Math.max(nextPage, 0), mPageCount - 1);
 }
예제 #8
0
 public static int calculateInSampleSize(
     BitmapFactory.Options options, int reqWidth, int reqHeight) {
   int h = options.outHeight;
   int w = options.outWidth;
   int inSampleSize = 0;
   if (h > reqHeight || w > reqWidth) {
     float ratioW = (float) w / reqWidth;
     float ratioH = (float) h / reqHeight;
     inSampleSize = (int) Math.min(ratioH, ratioW);
   }
   inSampleSize = Math.max(1, inSampleSize);
   return inSampleSize;
 }
 /**
  * 根据移动的距离来刷新原来的圆半径大小
  *
  * @param distance
  */
 private void refreshCurRadiusByMoveDistance(int distance) {
   if (distance > maxMoveLength) {
     isArrivedMaxMoved = true;
     curRadius = 0;
   } else {
     isArrivedMaxMoved = false;
     float calcRadius = (1 - 1f * distance / maxMoveLength) * originRadius;
     float maxRadius = ABTextUtil.dip2px(context, 2);
     curRadius = (int) Math.max(calcRadius, maxRadius);
     //            Logger.d(TAG, "[refreshCurRadiusByMoveDistance]curRadius: " + curRadius + ",
     // calcRadius: " + calcRadius + ", maxRadius: " + maxRadius);
   }
 }
  private void drawTown(Canvas canvas) {
    Matrix matrix = mMatrix;
    matrix.reset();

    int y = Math.max(0, mTop - mTotalDragDistance);
    float dragPercent = Math.min(1f, Math.abs(mPercent));

    float townScale;
    float townTopOffset;
    float townMoveOffset;
    float scalePercentDelta = dragPercent - SCALE_START_PERCENT;
    if (scalePercentDelta > 0) {
      /**
       * Change townScale between {@link #TOWN_INITIAL_SCALE} and {@link #TOWN_FINAL_SCALE}
       * depending on {@link #mPercent} Change townTopOffset between {@link #mTownInitialTopOffset}
       * and {@link #mTownFinalTopOffset} depending on {@link #mPercent}
       */
      float scalePercent = scalePercentDelta / (1.0f - SCALE_START_PERCENT);
      townScale = TOWN_INITIAL_SCALE + (TOWN_FINAL_SCALE - TOWN_INITIAL_SCALE) * scalePercent;
      townTopOffset =
          mTownInitialTopOffset - (mTownFinalTopOffset - mTownInitialTopOffset) * scalePercent;
      townMoveOffset = mTownMoveOffset * (1.0f - scalePercent);
    } else {
      float scalePercent = dragPercent / SCALE_START_PERCENT;
      townScale = TOWN_INITIAL_SCALE;
      townTopOffset = mTownInitialTopOffset;
      townMoveOffset = mTownMoveOffset * scalePercent;
    }

    float offsetX = -(mScreenWidth * townScale - mScreenWidth) / 2.0f;
    // float offsetY = (1.0f - dragPercent) * mTotalDragDistance // Offset canvas moving
    float offsetY =
        y
            + +townTopOffset
            - mTownHeight * (townScale - 1.0f) / 2 // Offset town scaling
            + townMoveOffset; // Give it a little move

    matrix.postScale(townScale, townScale);
    // 移动建筑的中心点
    matrix.postTranslate(offsetX, offsetY);

    canvas.drawBitmap(mTown, matrix, null);
  }
  private void drawSky(Canvas canvas) {
    Matrix matrix = mMatrix;
    matrix.reset();
    int y = Math.max(0, mTop - mTotalDragDistance);

    //  0  ~ 1
    float dragPercent = Math.min(1f, Math.abs(mPercent));

    /**
     * Change skyScale between {@link #SKY_INITIAL_SCALE} and 1.0f depending on {@link #mPercent}
     */
    // 根据拖动的比例改变天空的大小
    float skyScale;
    float scalePercentDelta = dragPercent - SCALE_START_PERCENT;

    /** less than {@link SCALE_START_PERCENT} will be {@link SKY_INITIAL_SCALE} */
    // 拖动比例小于0.3时使用默认的大小1.05
    if (scalePercentDelta > 0) {
      /** will change from 0 ~ 1 * */
      // skyScale = SKY_INITIAL_SCALE + (dragPercent - SCALE_START_PERCENT);
      float scalePercent = scalePercentDelta / (1.0f - SCALE_START_PERCENT);
      skyScale = SKY_INITIAL_SCALE - (SKY_INITIAL_SCALE - 1.0f) * scalePercent;
    } else {
      skyScale = SKY_INITIAL_SCALE;
    }

    float offsetX = -(mScreenWidth * skyScale - mScreenWidth) / 2.0f;

    float offsetY =
        y
            + 50
            + mSkyTopOffset // Offset canvas moving, goes lower when goes down
            - mSkyHeight
                * (skyScale - 1.0f)
                / 2 // Offset sky scaling, lower than 0, will go greater when goes down
            + mSkyMoveOffset
                * dragPercent; // Give it a little move top -> bottom  // will go greater when goes
                               // down

    matrix.postScale(skyScale, skyScale);
    matrix.postTranslate(offsetX, offsetY);
    canvas.drawBitmap(mSky, matrix, null);
  }
 private int getMaxScrollY() {
   return Math.max(0, sumArray(heights) - height);
 }
 private int getMaxScrollX() {
   return Math.max(0, sumArray(widths) - width);
 }
예제 #14
0
  // Audio
  public static int audioInit(
      int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
    int channelConfig =
        isStereo
            ? AudioFormat.CHANNEL_CONFIGURATION_STEREO
            : AudioFormat.CHANNEL_CONFIGURATION_MONO;
    int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
    int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);

    Log.v(
        "SDL",
        "SDL audio: wanted "
            + (isStereo ? "stereo" : "mono")
            + " "
            + (is16Bit ? "16-bit" : "8-bit")
            + " "
            + (sampleRate / 1000f)
            + "kHz, "
            + desiredFrames
            + " frames buffer");

    // Let the user pick a larger buffer if they really want -- but ye
    // gods they probably shouldn't, the minimums are horrifyingly high
    // latency already
    desiredFrames =
        Math.max(
            desiredFrames,
            (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1)
                / frameSize);

    if (mAudioTrack == null) {
      mAudioTrack =
          new AudioTrack(
              AudioManager.STREAM_MUSIC,
              sampleRate,
              channelConfig,
              audioFormat,
              desiredFrames * frameSize,
              AudioTrack.MODE_STREAM);

      // Instantiating AudioTrack can "succeed" without an exception and the track may still be
      // invalid
      // Ref:
      // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
      // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()

      if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
        Log.e("SDL", "Failed during initialization of Audio Track");
        mAudioTrack = null;
        return -1;
      }

      mAudioTrack.play();
    }

    Log.v(
        "SDL",
        "SDL audio: got "
            + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono")
            + " "
            + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT)
                ? "16-bit"
                : "8-bit")
            + " "
            + (mAudioTrack.getSampleRate() / 1000f)
            + "kHz, "
            + desiredFrames
            + " frames buffer");

    return 0;
  }
예제 #15
0
    public void build(MessageWireframe wireframe, int desiredWidth, StelsApplication application) {

      Logger.d(TAG, "Build layout start");

      checkResources(application);

      senderPaint = initTextPaint();
      senderPaint.setTypeface(FontController.loadTypeface(application, "regular"));
      senderPaint.setTextSize(bodyPaint.getTextSize());
      senderPaint.setColor(0xff000000);

      forwardingPaint = initTextPaint();
      forwardingPaint.setTypeface(FontController.loadTypeface(application, "light"));
      forwardingPaint.setTextSize(bodyPaint.getTextSize());
      forwardingPaint.setColor(0xff000000);

      this.layoutDesiredWidth = desiredWidth;
      this.isOut = wireframe.message.isOut();
      this.showState = isOut;
      this.isGroup = wireframe.message.getPeerType() == PeerType.PEER_CHAT && !isOut;
      if (isGroup) {
        User user = wireframe.senderUser;
        this.senderName = user.getDisplayName();
        if (!wireframe.message.isForwarded()) {
          senderPaint.setColor(
              Placeholders.USER_PLACEHOLDERS_COLOR[
                  wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]);
          forwardingPaint.setColor(
              Placeholders.USER_PLACEHOLDERS_COLOR[
                  wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]);
        }
      }

      if (wireframe.message.isForwarded()) {
        isForwarded = true;
        this.forwarderName = wireframe.forwardUser.getDisplayName();
        if (isOut) {
          forwardingPaint.setColor(0xff739f53);
          senderPaint.setColor(0xff739f53);
        } else {
          forwardingPaint.setColor(0xff4884cf);
          senderPaint.setColor(0xff4884cf);
        }
      } else {
        isForwarded = false;
      }

      if (isGroup) {
        User user = application.getEngine().getUser(wireframe.message.getSenderId());
        this.senderName = user.getDisplayName();
      }
      if (wireframe.message.isForwarded()) {
        isForwarded = true;
        this.forwarderName = wireframe.forwardUser.getDisplayName();
      } else {
        isForwarded = false;
      }

      layoutDesiredWidth = desiredWidth;
      long start = SystemClock.uptimeMillis();

      this.spannable =
          application
              .getEmojiProcessor()
              .processEmojiCompatMutable(
                  wireframe.message.getMessage(), EmojiProcessor.CONFIGURATION_BUBBLES);

      // spannable = new SpannableString(wireframe.message.getMessage());
      Logger.d(TAG, "Emoji processed in " + (SystemClock.uptimeMillis() - start) + " ms");
      start = SystemClock.uptimeMillis();
      Linkify.addLinks(
          this.spannable, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS | Linkify.EMAIL_ADDRESSES);
      fixLinks(spannable);
      Logger.d(TAG, "Added links in " + (SystemClock.uptimeMillis() - start) + " ms");
      start = SystemClock.uptimeMillis();
      layout =
          new StaticLayout(
              spannable, bodyPaint, desiredWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true);
      Logger.d(TAG, "Built base layout in " + (SystemClock.uptimeMillis() - start) + " ms");

      if (layout.getLineCount() < 20) {
        int layoutTextWidth = 0;

        for (int i = 0; i < layout.getLineCount(); i++) {
          layoutTextWidth = (int) Math.max(layout.getLineWidth(i), layoutTextWidth);
        }

        if (layoutTextWidth < layout.getWidth() - px(10)) {
          layout =
              new StaticLayout(
                  spannable,
                  bodyPaint,
                  layoutTextWidth + px(2),
                  Layout.Alignment.ALIGN_NORMAL,
                  1.0f,
                  0.0f,
                  true);
        }
      }

      layoutRealWidth = layout.getWidth();

      timeWidth = (int) clockOutPaint.measureText(wireframe.date) + px((showState ? 23 : 0) + 6);

      if (layout.getLineCount() == 1) {
        boolean isLastRtl = layout.getParagraphDirection(0) == Layout.DIR_RIGHT_TO_LEFT;
        if (!isLastRtl && desiredWidth - layoutRealWidth > timeWidth) {
          layoutRealWidth += timeWidth;
          layoutHeight = layout.getHeight() + px(3);
        } else if (isLastRtl && desiredWidth - layout.getWidth() > timeWidth) {
          layoutRealWidth = layout.getWidth() + timeWidth;
          layoutHeight = layout.getHeight() + px(3);
        } else {
          if (isLastRtl) {
            layoutRealWidth = layout.getWidth();
          }

          layoutHeight = layout.getHeight() + px(17);
        }
      } else {
        boolean isLastRtl =
            layout.getParagraphDirection(layout.getLineCount() - 1) == Layout.DIR_RIGHT_TO_LEFT;
        if (!isLastRtl
            && (desiredWidth - layout.getLineWidth(layout.getLineCount() - 1) > timeWidth)) {
          layoutRealWidth =
              (int)
                  Math.max(
                      layoutRealWidth, layout.getLineWidth(layout.getLineCount() - 1) + timeWidth);
          layoutHeight = layout.getHeight() + px(3);
        } else if (isLastRtl && (desiredWidth - layout.getWidth() > timeWidth)) {
          layoutRealWidth = (int) Math.max(layoutRealWidth, layout.getWidth() + timeWidth);
          layoutHeight = layout.getHeight() + px(3);
        } else {
          layoutHeight = layout.getHeight() + px(17);
        }
      }

      if (layoutRealWidth < timeWidth) {
        layoutRealWidth = timeWidth;
      }

      if (isForwarded) {
        layoutHeight += px(19) * 2;
        forwardOffset = (int) forwardingPaintBase.measureText("From ");
        layoutRealWidth =
            (int) Math.max(layoutRealWidth, forwardingPaintBase.measureText("Forwarded message"));
        forwarderNameMeasured =
            TextUtils.ellipsize(
                    forwarderName,
                    senderPaintBase,
                    desiredWidth - forwardOffset,
                    TextUtils.TruncateAt.END)
                .toString();
        layoutRealWidth =
            (int)
                Math.max(
                    layoutRealWidth,
                    forwardOffset + senderPaintBase.measureText(forwarderNameMeasured));
      }

      if (isGroup && !isOut && !isForwarded) {
        layoutHeight += px(19);
        senderNameMeasured =
            TextUtils.ellipsize(senderName, senderPaintBase, desiredWidth, TextUtils.TruncateAt.END)
                .toString();
        int width = (int) senderPaintBase.measureText(senderNameMeasured);
        layoutRealWidth = Math.max(layoutRealWidth, width);
      }

      Logger.d(TAG, "Build layout end");
    }