Commit 026eed03 authored by wanglei's avatar wanglei

...适配Android12启动页

parent 65845eb0

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

/build
\ No newline at end of file
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.cherry.lib.doc'
compileSdk 34
defaultConfig {
minSdk 21
targetSdk 34
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding = true
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.3'
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1"
implementation "androidx.lifecycle:lifecycle-common:2.4.1"
implementation("io.coil-kt:coil:1.4.0")
implementation 'org.apache.poi:poi-scratchpad:3.17'
// read file
implementation 'commons-io:commons-io:2.0.1'
// AndroidUtilCode工具类:https://github.com/Blankj/AndroidUtilCode
implementation('com.blankj:utilcodex:1.31.1')
// 文件编码判断:https://mvnrepository.com/artifact/com.googlecode.juniversalchardet/juniversalchardet
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.cherry.lib.doc
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.cherry.lib.doc.test", appContext.packageName)
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name=".DocViewerActivity" />
</application>
</manifest>
\ No newline at end of file
package com.cherry.lib.doc
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.cherry.lib.doc.bean.DocEngine
import com.cherry.lib.doc.util.Constant
import com.cherry.lib.doc.widget.DocView
open class DocViewerActivity : AppCompatActivity() {
private val TAG = "DocViewerActivity"
companion object {
fun launchDocViewer(
activity: AppCompatActivity, docSourceType: Int, path: String?,
fileType: Int? = null, engine: Int? = null
) {
val intent = Intent(activity, DocViewerActivity::class.java)
intent.putExtra(Constant.INTENT_SOURCE_KEY, docSourceType)
intent.putExtra(Constant.INTENT_DATA_KEY, path)
intent.putExtra(Constant.INTENT_TYPE_KEY, fileType)
intent.putExtra(Constant.INTENT_ENGINE_KEY, engine)
activity.startActivity(intent)
}
}
var docSourceType = 0
var fileType = -1
var engine: Int = DocEngine.INTERNAL.value
var docUrl: String? = null// 文件地址
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_doc_viewer)
initView()
initData(intent)
}
fun initView() {
}
fun initData(intent: Intent?) {
docUrl = intent?.getStringExtra(Constant.INTENT_DATA_KEY)
docSourceType = intent?.getIntExtra(Constant.INTENT_SOURCE_KEY, 0) ?: 0
fileType = intent?.getIntExtra(Constant.INTENT_TYPE_KEY, -1) ?: -1
engine = intent?.getIntExtra(Constant.INTENT_ENGINE_KEY, DocEngine.INTERNAL.value) ?: DocEngine.INTERNAL.value
findViewById<DocView>(R.id.mDocView).openDoc(
this,
docUrl,
docSourceType,
fileType, false)
Log.e(TAG, "initData-docUrl = $docUrl")
Log.e(TAG, "initData-docSourceType = $docSourceType")
Log.e(TAG, "initData-fileType = $fileType")
}
}
\ No newline at end of file
package com.cherry.lib.doc.bean
/**
* Created by Rajat on 11,July,2020
*/
enum class DocEngine(val value: Int) {
INTERNAL(100),
MICROSOFT(200),
XDOC(300),
GOOGLE(400)
}
\ No newline at end of file
package com.cherry.lib.doc.bean
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: DocMovingOrientation
* Author: Victor
* Date: 2023/11/02 20:08
* Description:
* -----------------------------------------------------------------
*/
enum class DocMovingOrientation(val orientation: Int) {
HORIZONTAL(0),
VERTICAL(1)
}
\ No newline at end of file
package com.cherry.lib.doc.bean
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: DocSourceType
* Author: Victor
* Date: 2023/09/28 16:02
* Description:
* -----------------------------------------------------------------
*/
object DocSourceType {
const val URL = 1//在线
const val URI = 2//文件选择
const val PATH = 3//sdcard
const val ASSETS = 4//assests
}
\ No newline at end of file
package com.cherry.lib.doc.bean
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: FileType
* Author: Victor
* Date: 2023/10/25 16:11
* Description:
* -----------------------------------------------------------------
*/
object FileType {
const val TXT = 1
const val PDF = 2
const val IMAGE = 3
const val DOC = 4
const val DOCX = 5
const val XLS = 6
const val XLSX = 7
const val PPT = 8
const val PPTX = 9
const val NOT_SUPPORT = 10
}
\ No newline at end of file
package com.cherry.lib.doc.interfaces
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: OnPdfPageChangeListener
* Author: Victor
* Date: 2023/10/31 11:12
* Description:
* -----------------------------------------------------------------
*/
interface OnDocPageChangeListener {
fun OnPageChanged(foundPosition: Int, totalPageCount: Int)
}
\ No newline at end of file
package com.cherry.lib.doc.interfaces
import android.content.Context
import kotlinx.coroutines.CoroutineScope
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: OnDownloadListener
* Author: Victor
* Date: 2023/10/31 10:55
* Description:
* -----------------------------------------------------------------
*/
interface OnDownloadListener {
fun getDownloadContext(): Context
fun onDownloadStart() {}
fun onDownloadProgress(currentBytes: Long, totalBytes: Long) {}
fun onDownloadSuccess(absolutePath: String) {}
fun onError(error: Throwable) {}
fun getCoroutineScope(): CoroutineScope
}
\ No newline at end of file
package com.cherry.lib.doc.interfaces
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: OnPdfItemClickListener
* Author: Victor
* Date: 2024/02/22 17:15
* Description:
* -----------------------------------------------------------------
*/
interface OnPdfItemClickListener {
fun OnPdfItemClick(position: Int)
}
\ No newline at end of file
package com.cherry.lib.doc.interfaces
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: OnWebLoadListener
* Author: Victor
* Date: 2023/10/31 11:06
* Description:
* -----------------------------------------------------------------
*/
interface OnWebLoadListener {
fun OnWebLoadProgress(progress: Int)
fun onTitle(title: String?)
}
\ No newline at end of file
package com.cherry.lib.doc.office;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.blankj.utilcode.util.AppUtils;
import com.cherry.lib.doc.office.common.IOfficeToPicture;
import com.cherry.lib.doc.office.constant.EventConstant;
import com.cherry.lib.doc.office.constant.wp.WPViewConstant;
import com.cherry.lib.doc.office.res.ResKit;
import com.cherry.lib.doc.office.system.IMainFrame;
import com.cherry.lib.doc.office.system.MainControl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
/**
* Created by zjt on 18-8-11.
*/
public abstract class IOffice implements IMainFrame {
private String TAG = "IOffice";
private MainControl control;
private boolean writeLog = true;
//view background
private Object bg = Color.LTGRAY;
private String tempFilePath;
public IOffice() {
initControl();
}
private void initControl() {
control = new MainControl(this);
control.setOffictToPicture(new IOfficeToPicture() {
public Bitmap getBitmap(int componentWidth, int componentHeight) {
if (componentWidth == 0 || componentHeight == 0) {
return null;
}
if (bitmap == null || bitmap.getWidth() != componentWidth || bitmap.getHeight() != componentHeight) {
// custom picture size
if (bitmap != null) {
bitmap.recycle();
}
bitmap = Bitmap.createBitmap((int) (componentWidth), (int) (componentHeight), Bitmap.Config.ARGB_8888);
}
return bitmap;
}
public void callBack(Bitmap bitmap) {
saveBitmapToFile(bitmap);
}
private Bitmap bitmap;
@Override
public void setModeType(byte modeType) {
}
@Override
public byte getModeType() {
return VIEW_CHANGE_END;
}
@Override
public boolean isZoom() {
return false;
}
@Override
public void dispose() {
}
});
}
private void saveBitmapToFile(Bitmap bitmap) {
Log.e(TAG,"saveBitmapToFile1");
if (bitmap == null) {
Log.e(TAG,"saveBitmapToFile2");
return;
}
if (tempFilePath == null) {
Log.e(TAG,"saveBitmapToFile3");
// 存在外部目录相册中会显示
// String state = Environment.getExternalStorageState();
// if (Environment.MEDIA_MOUNTED.equals(state)) {
// tempFilePath = Environment.getExternalStorageDirectory().getAbsolutePath();
// }
tempFilePath = "/data/data/" + AppUtils.getAppPackageName() + "/cache";
File file = new File(tempFilePath + File.separatorChar + "tempPic");
if (!file.exists()) {
file.mkdir();
}
tempFilePath = file.getAbsolutePath();
}
File file = new File(tempFilePath + File.separatorChar + "export_image.jpg");
try {
if (file.exists()) {
Log.e(TAG,"saveBitmapToFile4");
file.delete();
}
file.createNewFile();
FileOutputStream fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
fOut.flush();
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public View getView() {
return control.getView();
}
public void openFile(String filepath, int docSourceType, String fileType) {
getControl().openFile(filepath, docSourceType, fileType);
}
/**
* true: show message when zooming
* false: not show message when zooming
*
* @return
*/
public boolean isShowZoomingMsg() {
return true;
}
/**
* true: pop up dialog when throw err
* false: not pop up dialog when throw err
*
* @return
*/
public boolean isPopUpErrorDlg() {
return true;
}
@Override
public abstract Activity getActivity();
/**
* do action,this is method don't call <code>control.actionEvent</code> method, Easily lead to infinite loop
*
* @param actionID action ID
* @param obj acValue
* @return True if the listener has consumed the event, false otherwise.
*/
public boolean doActionEvent(int actionID, Object obj) {
Log.e(TAG, "doActionEvent actionID" + actionID);
try {
switch (actionID) {
case EventConstant.SYS_UPDATE_TOOLSBAR_BUTTON_STATUS: //update toolsbar state
updateToolsbarStatus();
break;
case EventConstant.APP_FINDING:
String content = ((String) obj).trim();
if (content.length() > 0 && control.getFind().find(content)) {
setFindBackForwardState(true);
}
break;
case EventConstant.SS_CHANGE_SHEET:
break;
default:
return false;
}
} catch (Exception e) {
control.getSysKit().getErrorKit().writerLog(e);
}
return true;
}
@Override
public void updateToolsbarStatus() {
}
@Override
public void setFindBackForwardState(boolean state) {
}
/**
*
*/
public int getBottomBarHeight() {
return 0;
}
/**
*
*/
public int getTopBarHeight() {
return 0;
}
public boolean onEventMethod(View v, MotionEvent e1, MotionEvent e2, float xValue, float yValue, byte eventMethodType) {
return false;
}
public void changePage() {
}
public MainControl getControl() {
return this.control;
}
/**
*
*/
public abstract String getAppName();
public abstract int getMovingOrientation();
/**
* 是否绘制页码
*/
public boolean isDrawPageNumber() {
return false;
}
/**
* 是否支持zoom in / zoom out
*/
public boolean isTouchZoom() {
return true;
}
/**
* Word application 默认视图(Normal or Page)
*
* @return WPViewConstant.PAGE_ROOT or WPViewConstant.NORMAL_ROOT
*/
public byte getWordDefaultView() {
return WPViewConstant.PAGE_ROOT;
}
/**
* normal view, changed after zoom bend, you need to re-layout
*
* @return true re-layout
* false don't re-layout
*/
public boolean isZoomAfterLayoutForWord() {
return true;
}
/**
*
*/
public void changeZoom() {
}
/**
*
*/
public void error(int errorCode) {
}
@Override
public void showProgressBar(boolean visible) {
}
@Override
public void updateViewImages(List<Integer> viewList) {
}
/**
* when need destroy the office engine instance callback this method
*/
public void destroyEngine() {
}
/**
* get Internationalization resource
*
* @param resName Internationalization resource name
*/
public String getLocalString(String resName) {
return ResKit.instance().getLocalString(resName);
}
@Override
public boolean isShowPasswordDlg() {
return true;
}
@Override
public boolean isShowProgressBar() {
return true;
}
@Override
public boolean isShowFindDlg() {
return true;
}
@Override
public boolean isShowTXTEncodeDlg() {
return true;
}
/**
*
*/
public String getTXTDefaultEncode() {
return "GBK";
}
@Override
public void completeLayout() {
}
@Override
public boolean isChangePage() {
return true;
}
/**
* @param saveLog
*/
public void setWriteLog(boolean saveLog) {
this.writeLog = saveLog;
}
/**
* @return
*/
public boolean isWriteLog() {
return writeLog;
}
@Override
public void setThumbnail(boolean isThumbnail) {
}
@Override
public boolean isThumbnail() {
return false;
}
/**
* get view backgrouond
*
* @return
*/
public Object getViewBackground() {
return bg;
}
/**
* set flag whether fitzoom can be larger than 100% but smaller than the max zoom
*
* @param ignoreOriginalSize
*/
public void setIgnoreOriginalSize(boolean ignoreOriginalSize) {
}
/**
* @return true fitzoom may be larger than 100% but smaller than the max zoom
* false fitzoom can not larger than 100%
*/
public boolean isIgnoreOriginalSize() {
return false;
}
public int getPageListViewMovingPosition() {
return getMovingOrientation();
}
/**
* @return
*/
public abstract File getTemporaryDirectory();
/**
* 释放内存
*/
public void dispose() {
if (control != null) {
control.dispose();
control = null;
}
}
}
\ No newline at end of file
/*
* 文件名称: CriticalLock.java
*
* 编译器: android2.2
* 时间: 上午10:22:11
*/
package com.cherry.lib.doc.office.common;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* TODO: 文件注释
* <p>
* <p>
* Read版本: Read V1.0
* <p>
* 作者: jqin
* <p>
* 日期: 2011-12-12
* <p>
* 负责人: jqin
* <p>
* 负责小组:
* <p>
* <p>
*/
public class CriticalLock
{
private CriticalLock()
{
}
public static void lock()
{
reentrantLock.lock();
}
public static void unlock()
{
reentrantLock.unlock();
}
private static Lock reentrantLock = new ReentrantLock();
}
/*
* 文件名称: ICustomDialog.java
*
* 编译器: android2.2
* 时间: 下午12:47:14
*/
package com.cherry.lib.doc.office.common;
public interface ICustomDialog
{
//password dialog
public static final byte DIALOGTYPE_PASSWORD = 0;
//txt encode dialog
public static final byte DIALOGTYPE_ENCODE = 1;
//loading dialog
public static final byte DIALOGTYPE_LOADING = 2;
//error dialog
public static final byte DIALOGTYPE_ERROR = 3;
//
public static final byte DIALOGTYPE_FIND = 4;
/**
*
* @param type dialog type
*/
public void showDialog(byte type);
/**
*
* @param type
*/
public void dismissDialog(byte type);
}
/*
* 文件名称: OfficeToPicture.java
*
* 编译器: android2.2
* 时间: 下午2:15:37
*/
package com.cherry.lib.doc.office.common;
import android.graphics.Bitmap;
/**
* Office 文档转换成图片的接口
* <p>
* <p>
* Read版本: Read V1.0
* <p>
* 作者: ljj8494
* <p>
* 日期: 2012-5-14
* <p>
* 负责人: ljj8494
* <p>
* 负责小组:
* <p>
* <p>
*/
public interface IOfficeToPicture
{
// 实现IOfficeToPicture接口的类路径
public static final String INSTANCE_CLASS_PATH = "com.cherry.lib.doc.office.officereader.OfficeToPicture";
// 视图发生变化时生成picture,例如滚动、fling进行中
public static final byte VIEW_CHANGING = 0;
// 视图发生变化结束后,例如滚动、fling、横竖屏切换结束后
public static final byte VIEW_CHANGE_END = VIEW_CHANGING + 1;
/**
* set mode type
* @param modeType
*/
public void setModeType(byte modeType);
/**
* 生成picture模式
*
* @ return = 0,视图发生变化时生成picture,例如滚动、fling进行中,
* = 1,视图发生变化结束后,例如滚动、fling、横竖屏切换结束后。
*/
public byte getModeType();
/**
* 获得converter to picture的Bitmap,如果返回空,则不生成picture
*
* @param visibleWidth engine组件的可视图宽度
* @param visibleHeight engine组件的可视图高度
* @return Bitmap Bitmap实例
*/
public Bitmap getBitmap(int visibleWidth, int visibleHeight);
/**
* picture 绘制完成,回调方法
*
* @param bitmap 绘制好的图片
*/
public void callBack(Bitmap bitmap);
/**
* 是否以zoom方式生成picture,此zoom是指office engine的size 和 bitmap size 之间的zoom。
* 例如 engine的size 1280 * 768,而bitmap size要求是845 * 480,这样的情况是否需要zoom。
*
* @return true do zoom
* false don’t zoom
*/
public boolean isZoom();
/**
*
*/
public void dispose();
}
/*
* 文件名称: ISlideShow.java
*
* 编译器: android2.2
* 时间: 上午9:58:39
*/
package com.cherry.lib.doc.office.common;
public interface ISlideShow
{
//slideshow type
//begin slideshow
public static final byte SlideShow_Begin = 0; //0
//exit slideshow
public static final byte SlideShow_Exit = SlideShow_Begin + 1; //1
//previous step of animation
public static final byte SlideShow_PreviousStep = SlideShow_Exit + 1; //2
//next step of animation
public static final byte SlideShow_NextStep = SlideShow_PreviousStep + 1;//3
//previous slide
public static final byte SlideShow_PreviousSlide = SlideShow_NextStep + 1;//4
//next slide
public static final byte SlideShow_NextSlide = SlideShow_PreviousSlide + 1;//5
// /**
// *
// * @param actionType
// */
// public void slideshow(byte actionType);
/**
* exit slideshow
*/
public void exit();
}
/*
* 文件名称: PaintKit.java
*
* 编译器: android2.2
* 时间: 下午1:42:18
*/
package com.cherry.lib.doc.office.common;
import com.cherry.lib.doc.office.constant.SSConstant;
import android.graphics.Paint;
import android.graphics.Typeface;
/**
* TODO: 文件注释
* <p>
* <p>
* Read版本: Read V1.0
* <p>
* 作者: jqin
* <p>
* 日期: 2011-12-7
* <p>
* 负责人: jqin
* <p>
* 负责小组:
* <p>
* <p>
*/
public class PaintKit
{
private Paint paint = null;
private static PaintKit pk = new PaintKit();
/**
*
*/
private PaintKit()
{
paint = new Paint();
paint.setTextSize(SSConstant.HEADER_TEXT_FONTSZIE);
paint.setTypeface(Typeface.SERIF);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setStrokeCap(Paint.Cap.ROUND);
}
/**
*
* @return
*/
public static PaintKit instance()
{
return pk;
}
public Paint getPaint()
{
paint.reset();
paint.setAntiAlias(true);
return paint;
}
}
/*
* 文件名称: Scrollbar.java
*
* 编译器: android2.2
* 时间: 下午2:30:54
*/
package com.cherry.lib.doc.office.common;
import com.cherry.lib.doc.office.java.awt.Dimension;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
/**
* TODO: 文件注释
* <p>
* <p>
* Read版本: Read V1.0
* <p>
* 作者: jqin
* <p>
* 日期: 2011-12-13
* <p>
* 负责人: jqin
* <p>
* 负责小组:
* <p>
* <p>
*/
public class Scrollbar
{
private final int SCROLLBAR_SIZE = 5;
private final int SCROLLBAR_OFFBORDER = 2;
private final int SCROLLBAR_COLOR_ALPHA = 125;
// scroll bar color
private final int SCROLLBAR_COLOR = 0x8f444444;/*0x8fcecfd6;*/
public void setPageSize(int width, int height)
{
this.pageSize.setSize(width, height);
}
/**
* call setPageSize to set page size before call draw function
* @param canvas
* @param zoom
*/
public void draw(Canvas canvas, int currentX, int currentY, Paint paint)
{
Rect clip = canvas.getClipBounds();
int oldColor = paint.getColor();
int alpha = paint.getAlpha();
paint.setColor(SCROLLBAR_COLOR);
paint.setAlpha(SCROLLBAR_COLOR_ALPHA);
if(pageSize.width > clip.right)
{
drawHorizontalScrollBar(canvas, currentX, paint);
}
if(pageSize.height > clip.bottom)
{
drawVerticalScrollBar(canvas, currentY, paint);
}
paint.setColor(oldColor);
paint.setAlpha(alpha);
}
/**
*
* @param canvas
* @param zoom
*/
private void drawHorizontalScrollBar(Canvas canvas, int currentX, Paint paint)
{
Rect clip = canvas.getClipBounds();
//horizontal scroll bar length
float length = clip.right * clip.right / pageSize.width;
float pixelSteps = pageSize.width / (float)clip.right;
//find the scroll bar rect
float left = (pageSize.width / 2 - currentX) / pixelSteps - length / 2;
rect.set(left, clip.bottom - SCROLLBAR_SIZE - SCROLLBAR_OFFBORDER, left + length, clip.bottom - SCROLLBAR_OFFBORDER);
canvas.drawRoundRect(rect, SCROLLBAR_SIZE / 2, SCROLLBAR_SIZE / 2, paint);
}
/**
*
* @param canvas
* @param zoom
*/
private void drawVerticalScrollBar(Canvas canvas, int currentY, Paint paint)
{
Rect clip = canvas.getClipBounds();
//vertical scroll bar length
float length = clip.bottom * clip.bottom / pageSize.height;
float pixelSteps = pageSize.height / (float)clip.bottom;
//find the scroll bar rect
float top = (pageSize.height / 2 - currentY) / pixelSteps - length / 2;
rect.set(clip.right - SCROLLBAR_SIZE - SCROLLBAR_OFFBORDER, top, clip.right - SCROLLBAR_OFFBORDER, top + length);
canvas.drawRoundRect(rect, SCROLLBAR_SIZE / 2, SCROLLBAR_SIZE / 2, paint);
}
//
private Dimension pageSize = new Dimension();
//
private RectF rect = new RectF();
}
/*
* 文件名称: PathExtend.java
*
* 编译器: android2.2
* 时间: 上午10:42:18
*/
package com.cherry.lib.doc.office.common.autoshape;
import com.cherry.lib.doc.office.common.bg.BackgroundAndFill;
import com.cherry.lib.doc.office.common.borders.Line;
import android.graphics.Path;
/**
* TODO: 文件注释
* <p>
* <p>
* Read版本: Read V1.0
* <p>
* 作者: jqin
* <p>
* 日期: 2012-9-27
* <p>
* 负责人: jqin
* <p>
* 负责小组:
* <p>
* <p>
*/
public class ExtendPath
{
public ExtendPath()
{
path = new Path();
fill = null;
}
public ExtendPath(ExtendPath extendPath)
{
path = new Path(extendPath.getPath());
fill = extendPath.getBackgroundAndFill();
hasLine = extendPath.hasLine();
line = extendPath.getLine();
isArrow = extendPath.isArrowPath();
}
public void setPath(Path path)
{
this.path = path;
}
public Path getPath()
{
return path;
}
public void setBackgroundAndFill(BackgroundAndFill fill)
{
this.fill = fill;
}
public BackgroundAndFill getBackgroundAndFill()
{
return fill;
}
/*
*
*/
public boolean hasLine()
{
return hasLine;
}
/**
*
* @param border
*/
public void setLine(boolean hasLine)
{
this.hasLine = hasLine;
if(hasLine && line == null)
{
line = new Line();
}
}
/**
*
* @return
*/
public Line getLine()
{
return line;
}
/**
*
*/
public void setLine(Line line)
{
this.line = line;
if(line != null)
{
hasLine = true;
}
else
{
hasLine = false;
}
}
public void setArrowFlag(boolean isArrow)
{
this.isArrow = isArrow;
}
public boolean isArrowPath()
{
return isArrow;
}
public void dispose()
{
path = null;
if(fill != null)
{
fill.dispose();
}
}
private Path path;
private BackgroundAndFill fill;
private boolean hasLine;
private Line line;
private boolean isArrow;
}
package com.cherry.lib.doc.office.common.autoshape.pathbuilder;
import android.graphics.Path;
import android.graphics.PointF;
public class ArrowPathAndTail
{
public void reset()
{
path = null;
tail = null;
}
public Path getArrowPath()
{
return path;
}
public void setArrowPath(Path path)
{
this.path = path;
}
public PointF getArrowTailCenter()
{
return tail;
}
public void setArrowTailCenter(float x, float y)
{
this.tail = new PointF(x, y);
}
//arrow path
private Path path;
//arrow tail center position
private PointF tail;
}
/*
* 文件名称: SimpleArrow.java
*
* 编译器: android2.2
* 时间: 下午3:07:55
*/
package com.cherry.lib.doc.office.common.autoshape.pathbuilder.arrow;
import com.cherry.lib.doc.office.common.shape.AutoShape;
import android.graphics.Rect;
/**
* TODO: LeftArrow, RightArrow, UpArrow, DownArrow, LeftRightArrow, UpDownArrow
* <p>
* <p>
* Read版本: Read V1.0
* <p>
* 作者: jqin
* <p>
* 日期: 2012-9-17
* <p>
* 负责人: jqin
* <p>
* 负责小组:
* <p>
* <p>
*/
public class ArrowPathBuilder
{
/**
* get autoshape path
* @param shape
* @param rect
* @return
*/
public static Object getArrowPath(AutoShape shape, Rect rect)
{
if(shape.isAutoShape07())
{
return LaterArrowPathBuilder.getArrowPath(shape, rect);
}
else
{
return EarlyArrowPathBuilder.getArrowPath(shape, rect);
}
}
}
/*
* 文件名称: EarlyStarPathBuilder.java
*
* 编译器: android2.2
* 时间: 下午3:38:00
*/
package com.cherry.lib.doc.office.common.autoshape.pathbuilder.starAndBanner.star;
import com.cherry.lib.doc.office.common.shape.AutoShape;
import com.cherry.lib.doc.office.common.shape.ShapeTypes;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
/**
* TODO: 文件注释
* <p>
* <p>
* Read版本: Read V1.0
* <p>
* 作者: jqin
* <p>
* 日期: 2012-10-19
* <p>
* 负责人: jqin
* <p>
* 负责小组:
* <p>
* <p>
*/
public class EarlyStarPathBuilder
{
private static Matrix sm = new Matrix();
public static RectF s_rect = new RectF();
public static Path getStarPath(AutoShape shape, Rect rect)
{
switch(shape.getShapeType())
{
case ShapeTypes.Star4:
return getStar4Path(shape, rect);
case ShapeTypes.Star5:
case ShapeTypes.Star:
return getStar5Path(shape, rect);
case ShapeTypes.Star8:
return getStar8Path(shape, rect);
case ShapeTypes.Star16:
return getStar16Path(shape, rect);
case ShapeTypes.Star24:
return getStar24Path(shape, rect);
case ShapeTypes.Star32:
return getStar32Path(shape, rect);
}
return null;
}
private static Path getStar4Path(AutoShape shape, Rect rect)
{
Float[] values = shape.getAdjustData();
float len = Math.min(rect.width(), rect.height());
float width = len, height = len;
float a = 0, b = 0;
if(values != null && values.length == 1)
{
if(values[0] > 0.5f)
{
values[0] = 0.5f;
}
a = len * (0.5f - values[0]);
b = len * (0.5f - values[0]);
}
else
{
a = len * 0.125f;
b = len * 0.125f;
}
float outA = width / 2;
float outB = height / 2;
Path path = StarPathBuilder.getStarPath((int)outA, (int)outB, (int)a, (int)b, 4);
sm.reset();
sm.postScale(rect.width() / len, rect.height() / len);
path.transform(sm);
path.offset(rect.centerX(), rect.centerY());
return path;
}
private static Path getStar5Path(AutoShape shape, Rect rect)
{
Float[] values = shape.getAdjustData();
float len = Math.min(rect.width(), rect.height());
float width = len, height = len;
float a = 0, b = 0;
width = width * 1.05146f;
height = height * 1.10557f;
a = width * 0.2f;
b = height * 0.2f;
float outA = width / 2;
float outB = height / 2;
Path path = StarPathBuilder.getStarPath((int)outA, (int)outB, (int)a, (int)b, 5);
sm.reset();
sm.postScale(rect.width() / len, rect.height() / len);
path.transform(sm);
height = height * rect.height() / len;
path.offset(rect.centerX(), rect.centerY() + (height - rect.height()) / 2);
return path;
}
private static Path getStar8Path(AutoShape shape, Rect rect)
{
Float[] values = shape.getAdjustData();
float len = Math.min(rect.width(), rect.height());
float width = len, height = len;
float a = 0, b = 0;
if(values != null && values.length == 1)
{
if(values[0] > 0.5f)
{
values[0] = 0.5f;
}
a = width * (0.5f - values[0]);
b = height * (0.5f - values[0]);
}
else
{
a = width * 0.375f;
b = height * 0.375f;
}
float outA = width / 2;
float outB = height / 2;
Path path = StarPathBuilder.getStarPath((int)outA, (int)outB, (int)a, (int)b, 8);
sm.reset();
sm.postScale(rect.width() / len, rect.height() / len);
path.transform(sm);
path.offset(rect.centerX(), rect.centerY());
return path;
}
private static Path getStar16Path(AutoShape shape, Rect rect)
{
Float[] values = shape.getAdjustData();
float len = Math.min(rect.width(), rect.height());
float width = len, height = len;
float a = 0, b = 0;
if(values != null && values.length == 1)
{
if(values[0] > 0.5f)
{
values[0] = 0.5f;
}
a = width * (0.5f - values[0]);
b = height * (0.5f - values[0]);
}
else
{
a = width * 0.375f;
b = height * 0.375f;
}
Path path = StarPathBuilder.getStarPath((int)width / 2, (int)height / 2, (int)a, (int)b, 16);
sm.reset();
sm.postScale(rect.width() / len, rect.height() / len);
path.transform(sm);
path.offset(rect.centerX(), rect.centerY());
return path;
}
private static Path getStar24Path(AutoShape shape, Rect rect)
{
Float[] values = shape.getAdjustData();
float len = Math.min(rect.width(), rect.height());
float width = len, height = len;
float a = 0, b = 0;
if(values != null && values.length == 1)
{
if(values[0] > 0.5f)
{
values[0] = 0.5f;
}
a = width * (0.5f - values[0]);
b = height * (0.5f - values[0]);
}
else
{
a = width * 0.375f;
b = height * 0.375f;
}
Path path = StarPathBuilder.getStarPath((int)width / 2, (int)height / 2, (int)a, (int)b, 24);
sm.reset();
sm.postScale(rect.width() / len, rect.height() / len);
path.transform(sm);
path.offset(rect.centerX(), rect.centerY());
return path;
}
private static Path getStar32Path(AutoShape shape, Rect rect)
{
Float[] values = shape.getAdjustData();
float len = Math.min(rect.width(), rect.height());
float width = len, height = len;
float a = 0, b = 0;
if(values != null && values.length == 1)
{
if(values[0] > 0.5f)
{
values[0] = 0.5f;
}
a = width * (0.5f - values[0]);
b = height * (0.5f - values[0]);
}
else
{
a = width * 0.375f;
b = height * 0.375f;
}
Path path = StarPathBuilder.getStarPath((int)width / 2, (int)height / 2, (int)a, (int)b, 32);
sm.reset();
sm.postScale(rect.width() / len, rect.height() / len);
path.transform(sm);
path.offset(rect.centerX(), rect.centerY());
return path;
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment