Pārlūkot izejas kodu

重写全屏预览、水印组件缩放策略;新增现存水印编辑功能;添加I18n、深色模式适配;对Android12以上支持MD3

dengyujia 2 gadi atpakaļ
vecāks
revīzija
8a55fe50a0
51 mainītis faili ar 2325 papildinājumiem un 407 dzēšanām
  1. 0 17
      .idea/deploymentTargetDropDown.xml
  2. 229 89
      app/src/main/java/com/compdfkit/pdfviewer/MainActivity.java
  3. 131 0
      app/src/main/java/com/compdfkit/pdfviewer/adapter/WatermarkListAdapter.java
  4. 0 4
      app/src/main/java/com/compdfkit/pdfviewer/builder/WatermarkBuilder.java
  5. 99 0
      app/src/main/java/com/compdfkit/pdfviewer/customview/WatermarkListItem.java
  6. 18 0
      app/src/main/java/com/compdfkit/pdfviewer/customview/WatermarkListView.java
  7. 0 98
      app/src/main/java/com/compdfkit/pdfviewer/customview/WatermarkView.java
  8. 26 11
      app/src/main/java/com/compdfkit/pdfviewer/customview/ImageWatermarkView.java
  9. 55 15
      app/src/main/java/com/compdfkit/pdfviewer/customview/TextWatermarkView.java
  10. 182 0
      app/src/main/java/com/compdfkit/pdfviewer/customview/watermarkview/WatermarkView.java
  11. 13 2
      app/src/main/java/com/compdfkit/pdfviewer/entity/WatermarkSetting.java
  12. 132 7
      app/src/main/java/com/compdfkit/pdfviewer/fragments/WatermarkConsoleFragment.java
  13. 27 0
      app/src/main/java/com/compdfkit/pdfviewer/tools/ConvertMapper.java
  14. 0 11
      app/src/main/java/com/compdfkit/pdfviewer/tools/CoordinateMapper.java
  15. 87 0
      app/src/main/java/com/compdfkit/pdfviewer/tools/WatermarkHandle.java
  16. 5 0
      app/src/main/res/drawable-v31/ic_baseline_done_24.xml
  17. 5 0
      app/src/main/res/drawable-v31/ic_baseline_edit_note_24.xml
  18. 5 0
      app/src/main/res/drawable-v31/ic_baseline_format_size_20.xml
  19. 5 0
      app/src/main/res/drawable-v31/ic_baseline_opacity_20.xml
  20. 5 0
      app/src/main/res/drawable-v31/ic_baseline_watermark_add_24.xml
  21. 8 0
      app/src/main/res/drawable/delete_view.xml
  22. 5 0
      app/src/main/res/drawable/ic_baseline_delete_forever_24.xml
  23. 5 0
      app/src/main/res/drawable/ic_baseline_edit_note_24.xml
  24. 5 0
      app/src/main/res/drawable/ic_baseline_image_type_24.xml
  25. 5 0
      app/src/main/res/drawable/ic_baseline_keyboard_arrow_right_24.xml
  26. 5 0
      app/src/main/res/drawable/ic_baseline_text_type_24.xml
  27. 5 0
      app/src/main/res/drawable/ic_baseline_watermark_add_24.xml
  28. 8 0
      app/src/main/res/drawable/watermark_item_light.xml
  29. 134 0
      app/src/main/res/layout-land-v31/activity_main.xml
  30. 346 0
      app/src/main/res/layout-land-v31/fragment_watermark_console.xml
  31. 39 4
      app/src/main/res/layout-land/activity_main.xml
  32. 23 10
      app/src/main/res/layout-land/fragment_watermark_console.xml
  33. 134 0
      app/src/main/res/layout-v31/activity_main.xml
  34. 347 0
      app/src/main/res/layout-v31/fragment_watermark_console.xml
  35. 46 10
      app/src/main/res/layout/activity_main.xml
  36. 13 12
      app/src/main/res/layout/fragment_watermark_console.xml
  37. 2 2
      app/src/main/res/layout/range_selector.xml
  38. 1 1
      app/src/main/res/layout/watermark_image_view.xml
  39. 41 0
      app/src/main/res/layout/watermark_item.xml
  40. 36 0
      app/src/main/res/layout/watermark_item_layout.xml
  41. 1 1
      app/src/main/res/layout/watermark_text_view.xml
  42. 0 105
      app/src/main/res/layout/watermark_view.xml
  43. 7 0
      app/src/main/res/menu/menu_done.xml
  44. 18 0
      app/src/main/res/values-night-v31/themes.xml
  45. 2 1
      app/src/main/res/values-night/themes.xml
  46. 19 0
      app/src/main/res/values-notnight-v31/themes.xml
  47. 30 0
      app/src/main/res/values-zh/strings.xml
  48. 1 0
      app/src/main/res/values/colors.xml
  49. 9 3
      app/src/main/res/values/strings.xml
  50. 1 1
      app/src/main/res/values/styles.xml
  51. 5 3
      app/src/main/res/values/themes.xml

+ 0 - 17
.idea/deploymentTargetDropDown.xml

@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="deploymentTargetDropDown">
-    <runningDeviceTargetSelectedWithDropDown>
-      <Target>
-        <type value="RUNNING_DEVICE_TARGET" />
-        <deviceKey>
-          <Key>
-            <type value="SERIAL_NUMBER" />
-            <value value="9A241FFBA005YG" />
-          </Key>
-        </deviceKey>
-      </Target>
-    </runningDeviceTargetSelectedWithDropDown>
-    <timeTargetWasSelectedWithDropDown value="2022-11-29T09:47:46.949607100Z" />
-  </component>
-</project>

+ 229 - 89
app/src/main/java/com/compdfkit/pdfviewer/MainActivity.java

@@ -1,16 +1,22 @@
 package com.compdfkit.pdfviewer;
 
+import static android.content.ContentValues.TAG;
+
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.AppCompatImageButton;
 import androidx.appcompat.widget.Toolbar;
-import androidx.core.content.ContextCompat;
 import androidx.core.view.MenuProvider;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
 
 import android.content.Intent;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -22,31 +28,35 @@ import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.ImageView;
 import android.widget.Toast;
 
 import com.compdfkit.core.common.CPDFDocumentException;
 import com.compdfkit.core.document.CPDFDocument;
 import com.compdfkit.core.page.CPDFPage;
-import com.compdfkit.core.utils.ColorUtils;
 import com.compdfkit.core.watermark.CPDFImageWatermark;
-import com.compdfkit.core.watermark.CPDFTextWatermark;
 import com.compdfkit.core.watermark.CPDFWatermark;
-import com.compdfkit.pdfviewer.customview.ImageWatermarkView;
-import com.compdfkit.pdfviewer.customview.TextWatermarkView;
-import com.compdfkit.pdfviewer.customview.WatermarkView;
+import com.compdfkit.pdfviewer.adapter.WatermarkListAdapter;
+import com.compdfkit.pdfviewer.customview.watermarkview.ImageWatermarkView;
+import com.compdfkit.pdfviewer.customview.watermarkview.TextWatermarkView;
+import com.compdfkit.pdfviewer.customview.watermarkview.WatermarkView;
 import com.compdfkit.pdfviewer.entity.WatermarkSetting;
 import com.compdfkit.pdfviewer.fragments.WatermarkConsoleFragment;
-import com.compdfkit.pdfviewer.tools.CoordinateMapper;
-import com.compdfkit.ui.reader.CPDFReaderView;
+import com.compdfkit.pdfviewer.tools.ConvertMapper;
+import com.compdfkit.pdfviewer.tools.WatermarkHandle;
 import com.google.android.material.tabs.TabLayout;
 
-import org.w3c.dom.Text;
-
 import java.io.File;
+import java.util.Objects;
 
 public class MainActivity extends AppCompatActivity implements MenuProvider {
     private ImageView pageImage;
+    private ImageView fullScreenMask;
+
+    private AppCompatImageButton expandListBtn;
+    private RecyclerView watermarkList;
+    private WatermarkListAdapter adapter;
 
     private CPDFDocument document = new CPDFDocument(this);
     private WatermarkView watermark;
@@ -55,9 +65,16 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
     private int currentPageHeight = 0;
     private int currentPageWidth = 0;
 
-    private float sizeConvertRate = 0;
+    private int imageHeight;
+    private int imageWidth;
+
+    private int cacheIndex = -1;
+
+    private boolean editMode = false;
+
+    private WatermarkSetting watermarkSettingCache;
 
-    private CPDFPage testPage;
+    private float sizeConvertRate = 0;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -65,6 +82,11 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
         setContentView(R.layout.activity_main);
         addMenuProvider(this);
 
+        if (this.getResources().getConfiguration().uiMode == 0x11) {
+            WindowInsetsControllerCompat wic = ViewCompat.getWindowInsetsController(getWindow().getDecorView());
+            wic.setAppearanceLightStatusBars(true);
+        }
+
         Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
 
@@ -75,16 +97,24 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
         consoleFragment.setAssociatedWatermark(watermark);
 
         pageImage = findViewById(R.id.page_image);
+        fullScreenMask = findViewById(R.id.full_screen_mask);
+
+        expandListBtn = findViewById(R.id.expand_list_btn);
+        expandListBtn.setOnClickListener(view -> {
+            try {
+                expandWatermarkList();
+            } catch (CPDFDocumentException e) {
+                e.printStackTrace();
+            }
+        });
+
+        watermarkList = findViewById(R.id.watermark_list);
 
         TabLayout tabLayout = findViewById(R.id.tab_layout);
         tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
             @Override
             public void onTabSelected(TabLayout.Tab tab) {
                 changeWatermark(tab.getPosition());
-
-                consoleFragment.setAssociatedWatermark(watermark);
-                consoleFragment.changePicker(tab.getPosition());
-                watermark = tab.getPosition() == 0 ? findViewById(R.id.watermark_text) : findViewById(R.id.watermark_image);
             }
 
             @Override
@@ -103,27 +133,21 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
         File PDFFile = new File("/storage/emulated/0/TestPDFs/test.pdf");
         Uri PDFUri = Uri.fromFile(PDFFile);
 
-        CPDFDocument.PDFDocumentError error = document.open(PDFFile.getAbsolutePath());
-
-        if (error == CPDFDocument.PDFDocumentError.PDFDocumentErrorPassword) {
-            error = document.open(PDFUri, "password");
-        } else if (error == CPDFDocument.PDFDocumentError.PDFDocumentErrorSuccess) {
-            Toast.makeText(this, "File:" + document.getFileName() + " open success.", Toast.LENGTH_SHORT).show();
-        } else {
-            Toast.makeText(this, "File failed.", Toast.LENGTH_SHORT).show();
-        }
+        reloadDocument(PDFFile, PDFUri);
 
+        consoleFragment.setDocumentPageCount(document.getPageCount());
         CPDFPage currentPage = document.pageAtIndex(0);
-        testPage = currentPage;
 
         RectF pageSize = document.getPageSize(0);
         float pageW = pageSize.right - pageSize.left;
         float pageH = pageSize.bottom - pageSize.top;
 
         pageImage.post(() -> {
-            int imageHeight = pageImage.getHeight();
+            imageHeight = pageImage.getHeight();
             sizeConvertRate = pageImage.getHeight() / pageH;
-            int imageWidth = (int) (sizeConvertRate * pageW);
+            imageWidth = (int) (sizeConvertRate * pageW);
+
+            pageImage.setMaxWidth(imageWidth);
 
             TextWatermarkView tempT = (TextWatermarkView) watermark;
             tempT.setSizeConvertRate(sizeConvertRate);
@@ -132,16 +156,15 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
 
             currentPageHeight = pageImage.getHeight();
             currentPageWidth = imageWidth;
-            Bitmap pageBitmap = Bitmap.createBitmap(imageWidth, pageImage.getHeight(), Bitmap.Config.ARGB_4444);
+            Bitmap pageBitmap = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_4444);
 
             currentPage.renderPage(pageBitmap, 0, 0, imageWidth, pageImage.getHeight(), 0xFFFFFFFF, 255, 0, true, true);
             refreshPageImage(pageBitmap);
+            fullScreenMask.setImageBitmap(pageBitmap);
 
             pageImage.setOnDragListener(new View.OnDragListener() {
                 float currentSlope;
 
-                final float convertRate = (float) (180 / 3.141592653);
-
                 double currentRotation = 0;
                 double resultRotation = 0;
 
@@ -164,15 +187,18 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
                                 watermark.setX(dragEvent.getX() + xOutline - xOffset);
                                 watermark.setY(dragEvent.getY() + yOutline - yOffset);
 
-                                watermark.setPDFXOffset(CoordinateMapper.convertViewXtoPDFXOffset(watermark.getX() - pageImage.getLeft(), xOffset, imageWidth / 2, sizeConvertRate));
-                                watermark.setPDFYOffset(CoordinateMapper.convertViewYtoPDFYOffset(watermark.getY() - pageImage.getTop(), yOffset, imageHeight / 2, sizeConvertRate));
+                                watermark.setPDFXOffset(ConvertMapper.convertViewXToPDFXOffset(watermark.getX() - pageImage.getLeft(), xOffset, imageWidth / 2f, sizeConvertRate));
+                                watermark.setPDFYOffset(ConvertMapper.convertViewYToPDFYOffset(watermark.getY() - pageImage.getTop(), yOffset, imageHeight / 2f, sizeConvertRate));
+
+                                watermark.setViewXOffset(watermark.getPDFXOffset() * sizeConvertRate);
+                                watermark.setViewYOffset(watermark.getPDFYOffset() * sizeConvertRate);
 
 //                                Log.d("DragTest", "Drag Location: (" + dragEvent.getX() + "," + dragEvent.getY() + ")");
 //                                Log.d("DragTest", "Watermark Location: (" + location[0] + "," + location[1] + ")");
 //                                Log.d("DragTest", "Watermark get xy: (" + watermark.getX() + "," + watermark.getY() + ")");
 //                                Log.d("DragTest", "pdf page w h: (" + pageW + "," + pageH + ")");
-//                                Log.d("DragTest", "Watermark get PDF xy: (" + CoordinateMapper.convertViewXtoPDFXOffset(watermark.getX() - pageImage.getLeft(), xOffset, imageWidth / 2, sizeConvertRate)
-//                                        + "," + CoordinateMapper.convertViewYtoPDFYOffset(watermark.getY() - pageImage.getTop(), yOffset, imageHeight / 2, sizeConvertRate) + ")");
+//                                Log.d("DragTest", "Watermark get PDF xy: (" + ConvertMapper.convertViewXtoPDFXOffset(watermark.getX() - pageImage.getLeft(), xOffset, imageWidth / 2, sizeConvertRate)
+//                                        + "," + ConvertMapper.convertViewYtoPDFYOffset(watermark.getY() - pageImage.getTop(), yOffset, imageHeight / 2, sizeConvertRate) + ")");
                                 return true;
                             case DragEvent.ACTION_DRAG_ENDED:
                                 watermark.setVisibility(View.VISIBLE);
@@ -192,19 +218,18 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
                         float centerPointY = watermark.getY() + 1.0f * watermark.getHeight() / 2; /* 控件中心点y = 当前控件位置y + 控件一半高度 */
 
                         if (dragEvent.getAction() == DragEvent.ACTION_DRAG_LOCATION) {
-                            //TODO:该部分的取坐标存在冗余代码
                             currentSlope = (dragEvent.getY() + pageImage.getTop() - centerPointY) / (dragEvent.getX() + pageImage.getLeft() - centerPointX) * -1;
-                            currentRotation = Math.atan(currentSlope) * convertRate;
+                            currentRotation = Math.toDegrees(Math.atan(currentSlope));
 
                             if ((dragEvent.getY() + pageImage.getTop() < centerPointY && dragEvent.getX() + pageImage.getLeft() < centerPointX) || (dragEvent.getY() + pageImage.getTop() > centerPointY && dragEvent.getX() + pageImage.getLeft() < centerPointX)) {
                                 currentRotation += 180;
-                                currentSlope += 3.1415926f;
+                                currentSlope += Math.PI;
                             }
 
-                            resultRotation = currentRotation - Math.atan(baseSlope) * convertRate;
+                            resultRotation = currentRotation - Math.toDegrees(Math.atan(baseSlope));
 
                             watermark.setRotation((float) resultRotation * -1);
-                            watermark.setRotationRadian((float) (resultRotation / convertRate));
+                            watermark.setRotationRadian((float) Math.toRadians(resultRotation));
 //                                Log.d("RollTest", "Current slope: " + currentSlope + ", Result rotation: " + resultRotation + ", Current rotation: " + currentRotation);
                             return true;
                         }
@@ -214,13 +239,29 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
             });
         });
 
-        Log.d("Render. Watermark Count", "current watermark count:" + document.getWatermarkCount());
+        watermarkList.post(() -> {
+            int watermarkCount = document.getWatermarkCount();
 
+            for (int i = 0; i < watermarkCount; i++) {
+                CPDFWatermark tempWatermark = document.getWatermark(i);
+                WatermarkHandle.addSettingIntoList(tempWatermark);
+            }
+
+            adapter = new WatermarkListAdapter(MainActivity.this, consoleFragment, WatermarkHandle.getSettingList());
+            watermarkList.setAdapter(adapter);
+
+            LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
+            watermarkList.setLayoutManager(manager);
+
+            watermarkList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
+        });
+
+        Log.d("Render. Watermark Count", "current watermark count:" + document.getWatermarkCount());
     }
 
     @Override
     public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
-        menuInflater.inflate(R.menu.menu_done, menu);
+        menuInflater.inflate(R.menu.menu_prime, menu);
     }
 
     @Override
@@ -228,6 +269,20 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
         return false;
     }
 
+    public void changeWatermarkLocation(float x, float y) {
+        float xOffset = 1.0f * watermark.getWidth() / 2;
+        float yOffset = 1.0f * watermark.getHeight() / 2;
+
+        watermark.setX(ConvertMapper.convertPDFXOffsetToViewX(x, xOffset, imageWidth / 2f, sizeConvertRate) + pageImage.getLeft());
+        watermark.setY(ConvertMapper.convertPDFYOffsetToViewY(y, yOffset, imageHeight / 2f, sizeConvertRate) + pageImage.getTop());
+
+        watermark.setPDFXOffset(x);
+        watermark.setPDFYOffset(y);
+
+        watermark.setViewXOffset(x * sizeConvertRate);
+        watermark.setViewYOffset(y * sizeConvertRate);
+    }
+
     public void changeWatermark(int type) {
         watermark.setVisibility(View.INVISIBLE);
         if (type == 1) {
@@ -236,53 +291,105 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
             watermark = findViewById(R.id.watermark_text);
         }
         watermark.setVisibility(View.VISIBLE);
+
+        consoleFragment.setAssociatedWatermark(watermark);
+        consoleFragment.changePicker(type);
     }
 
     public void refreshPageImage(Bitmap updatePageBitmap) {
         pageImage.setImageBitmap(updatePageBitmap);
     }
 
-    public void finishEditWatermark(MenuItem menuItem) throws CPDFDocumentException {
-        WatermarkSetting setting = consoleFragment.getWatermarkSetting();
-        watermark.completeSetting(setting);
+    public void reloadDocument(File PDFFile, Uri PDFUri) {
+        CPDFDocument.PDFDocumentError error = document.open(PDFFile.getAbsolutePath());
 
+        if (error == CPDFDocument.PDFDocumentError.PDFDocumentErrorPassword) {
+            error = document.open(PDFUri, "password");
+        } else if (error == CPDFDocument.PDFDocumentError.PDFDocumentErrorSuccess) {
+//            Toast.makeText(this, "File:" + document.getFileName() + " open success.", Toast.LENGTH_SHORT).show();
+        } else {
+            Toast.makeText(this, "File failed.", Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    public void createNewWatermark(WatermarkSetting setting) {
         CPDFWatermark.Type[] types = {CPDFWatermark.Type.WATERMARK_TYPE_TEXT, CPDFWatermark.Type.WATERMARK_TYPE_IMG};
+        CPDFWatermark currentWatermark = document.createWatermark(types[consoleFragment.getMode()]);
 
-        CPDFWatermark watermark;
-        watermark = document.createWatermark(types[consoleFragment.getMode()]);
-        try {
-            if (watermark != null && watermark.isValid()) {
-                if (setting.getImage() != null)
-                    watermark.setImage(setting.getImage(), (int) (setting.getiWidth() * sizeConvertRate), (int) (setting.getiHeight() * sizeConvertRate));
-                watermark.setText(setting.getText()); //设置文本
-                watermark.setFontName(setting.getFontName()); //设置字体
-                watermark.setTextRGBColor(setting.getTextRGBColor());
-                watermark.setOpacity(setting.getOpacity());
-                watermark.setFontSize(setting.getFontSize());
-                watermark.setFront(true);
-                watermark.setVertalign(CPDFWatermark.Vertalign.WATERMARK_VERTALIGN_CENTER);
-                watermark.setHorizalign(CPDFWatermark.Horizalign.WATERMARK_HORIZALIGN_CENTER);
-                watermark.setVertOffset(setting.getVertOffset());
-                watermark.setHorizOffset(setting.getHorizOffset());
-                watermark.setRotation(setting.getRotation());
-                watermark.setScale(setting.getScale());
-                watermark.setPages(setting.getPages());
-                watermark.setFullScreen(setting.getFullScreen());
-                watermark.setHorizontalSpacing(setting.getHorizontalSpacing());
-                watermark.setVerticalSpacing(setting.getVerticalSpacing());
-                watermark.update();
-            }
-        } finally {
-            if (watermark != null && watermark.isValid()) {
-                watermark.release();
-            }
+        WatermarkHandle.updateWatermark(currentWatermark, setting, sizeConvertRate);
+        adapter.addSettingIntoList(setting);
+    }
+
+    public void changeWatermark(CPDFWatermark watermark, WatermarkSetting setting) {
+        WatermarkHandle.updateWatermark(watermark, setting, sizeConvertRate);
+        adapter.updateSettingList(cacheIndex, setting);
+    }
+
+    public void deleteWatermark(int deleteIndex) throws CPDFDocumentException {
+        CPDFWatermark targetWatermark = document.getWatermark(deleteIndex);
+        targetWatermark.clear();
+
+        adapter.deleteSettingFromList(deleteIndex);
+        reloadDocument();
+    }
+
+    public void showFullScreenMask(boolean isFullScreen) {
+        if (isFullScreen) {
+            int imageHeight = pageImage.getHeight();
+            int imageWidth = pageImage.getWidth();
+
+            WatermarkView temp = watermark;
+
+            Bitmap fullScreenBitmap = temp.getFullScreenBitmap(imageWidth, imageHeight,
+                    (int) ConvertMapper.convertMMtoViewUnit(consoleFragment.gethSpace(), sizeConvertRate),
+                    (int) ConvertMapper.convertMMtoViewUnit(consoleFragment.getvSpace(), sizeConvertRate),
+                    (int) watermark.getViewXOffset(),
+                    (int) watermark.getViewYOffset(),
+                    watermark.getRotation());
+            fullScreenMask.setImageBitmap(fullScreenBitmap);
+            fullScreenMask.setAlpha(consoleFragment.getCurrentOpacity());
+            fullScreenMask.setVisibility(View.VISIBLE);
+            watermark.setVisibility(View.INVISIBLE);
+        } else {
+            fullScreenMask.setVisibility(View.INVISIBLE);
+            watermark.setVisibility(View.VISIBLE);
         }
+    }
 
-        Log.d("Finish. Watermark Count", "current watermark count:" + document.getWatermarkCount());
+    public void resetWatermark(int index) {
+        if (index == -1 || index == cacheIndex)
+            return;
+
+        CPDFWatermark tempWatermark = document.getWatermark(index);
+        WatermarkHandle.updateWatermark(tempWatermark, watermarkSettingCache, sizeConvertRate);
+    }
 
+    public void hideWatermark(int index) throws CPDFDocumentException {
+        CPDFWatermark currentWatermark = document.getWatermark(index);
+        if (index == cacheIndex)
+            return;
+
+        resetWatermark(cacheIndex);
+        cacheIndex = index;
+        watermarkSettingCache = WatermarkHandle.getSettingFromList(index);
+
+        if (currentWatermark.getType() == CPDFWatermark.Type.WATERMARK_TYPE_IMG) {
+            CPDFImageWatermark imageWatermark = (CPDFImageWatermark) currentWatermark;
+            imageWatermark.setOpacity(0f);
+            imageWatermark.update();
+        } else {
+            currentWatermark.setOpacity(0f);
+            currentWatermark.update();
+        }
+
+        Log.d(TAG, "hideWatermark: current watermark count:" + document.getWatermarkCount());
+
+        reloadDocument();
+    }
+
+    public void reloadDocument() throws CPDFDocumentException {
         if (document.hasChanges()) {
             boolean res;
-            //Save to original document
             res = document.save();
         }
         document.close();
@@ -290,22 +397,55 @@ public class MainActivity extends AppCompatActivity implements MenuProvider {
         File PDFFile = new File("/storage/emulated/0/TestPDFs/test.pdf");
         Uri PDFUri = Uri.fromFile(PDFFile);
 
-        CPDFDocument.PDFDocumentError error = document.open(PDFFile.getAbsolutePath());
-
-        if (error == CPDFDocument.PDFDocumentError.PDFDocumentErrorPassword) {
-            error = document.open(PDFUri, "password");
-        } else if (error == CPDFDocument.PDFDocumentError.PDFDocumentErrorSuccess) {
-            Toast.makeText(this, "File:" + document.getFileName() + " open success.", Toast.LENGTH_SHORT).show();
-        } else {
-            Toast.makeText(this, "File failed.", Toast.LENGTH_SHORT).show();
-        }
-
+        reloadDocument(PDFFile, PDFUri);
         CPDFPage currentPage = document.pageAtIndex(0);
-//        currentPage.equals(testPage)
-        Log.d("Finish EditWatermark", "the equal's result:" + (currentPage.equals(testPage)) );
 
         Bitmap pageBitmap = Bitmap.createBitmap(currentPageWidth, currentPageHeight, Bitmap.Config.ARGB_4444);
         currentPage.renderPage(pageBitmap, 0, 0, currentPageWidth, currentPageHeight, 0xFFFFFFFF, 255, 0, true, true);
         refreshPageImage(pageBitmap);
     }
+
+    public void finishEditWatermark(MenuItem menuItem) throws CPDFDocumentException {
+        WatermarkSetting setting = consoleFragment.getWatermarkSetting();
+        watermark.completeSetting(setting);
+
+        if (!editMode) {
+            createNewWatermark(setting);
+            Toast.makeText(this, "Add new watermark", Toast.LENGTH_SHORT).show();
+        } else {
+            changeWatermark(document.getWatermark(cacheIndex), setting);
+            Toast.makeText(this, "Change a watermark, index:" + cacheIndex, Toast.LENGTH_SHORT).show();
+
+            cacheIndex = -1;
+        }
+        Log.d("Finish. Watermark Count", "current watermark count:" + document.getWatermarkCount());
+
+        reloadDocument();
+    }
+
+    public void changeEditMode(MenuItem menuItem) {
+        editMode = !editMode;
+
+        Objects.requireNonNull(getSupportActionBar()).setTitle(editMode ? R.string.edit_watermark : R.string.add_watermark);
+        menuItem.setIcon(editMode ? R.drawable.ic_baseline_watermark_add_24 : R.drawable.ic_baseline_edit_note_24);
+
+        watermark.setVisibility(editMode ? View.INVISIBLE : View.VISIBLE);
+        watermarkList.setVisibility(editMode ? View.VISIBLE : View.INVISIBLE);
+        if (!editMode) {
+            expandListBtn.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    public void expandWatermarkList() throws CPDFDocumentException {
+        resetWatermark(cacheIndex);
+        watermark.setVisibility(View.INVISIBLE);
+        watermarkList.setVisibility(View.VISIBLE);
+        reloadDocument();
+    }
+
+    public void closeWatermarkList() {
+        expandListBtn.setVisibility(View.VISIBLE);
+        watermarkList.setVisibility(View.INVISIBLE);
+    }
+
 }

+ 131 - 0
app/src/main/java/com/compdfkit/pdfviewer/adapter/WatermarkListAdapter.java

@@ -0,0 +1,131 @@
+package com.compdfkit.pdfviewer.adapter;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.compdfkit.core.common.CPDFDocumentException;
+import com.compdfkit.pdfviewer.MainActivity;
+import com.compdfkit.pdfviewer.R;
+import com.compdfkit.pdfviewer.customview.WatermarkListItem;
+import com.compdfkit.pdfviewer.entity.WatermarkSetting;
+import com.compdfkit.pdfviewer.fragments.WatermarkConsoleFragment;
+import com.compdfkit.pdfviewer.tools.WatermarkHandle;
+
+import java.util.ArrayList;
+
+public class WatermarkListAdapter extends RecyclerView.Adapter<WatermarkListAdapter.WatermarkItemHolder>{
+    private final WatermarkConsoleFragment console;
+
+    private final Context context;
+    private View watermarkListView;
+
+    private int itemViewState = 0;
+
+    private final ArrayList<WatermarkSetting> settings;
+
+    public WatermarkListAdapter(Context context, WatermarkConsoleFragment console, ArrayList<WatermarkSetting> settings) {
+        this.context = context;
+        this.console = console;
+        this.settings = settings;
+    }
+
+    @NonNull
+    @Override
+    public WatermarkItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        watermarkListView = LayoutInflater.from(parent.getContext()).inflate(R.layout.watermark_item_layout, parent, false);
+
+        return new WatermarkItemHolder(watermarkListView);
+    }
+
+    @SuppressLint("UseCompatLoadingForDrawables")
+    @Override
+    public void onBindViewHolder(@NonNull WatermarkItemHolder holder, int position) {
+
+        WatermarkSetting currentSetting = settings.get(position);
+
+        holder.item.setWatermarkTypeIcon(context.getResources().getDrawable(currentSetting.getType() == 0 ? R.drawable.ic_baseline_text_type_24 : R.drawable.ic_baseline_image_type_24));
+        holder.item.setWatermarkContentText(currentSetting.getType() == 0 ? currentSetting.getText() : "Image\nwatermark");
+
+        holder.itemView.setOnClickListener(view -> {
+            WatermarkSetting setting = settings.get(holder.getAdapterPosition());
+            try {
+                console.resetWatermarkFromSetting(holder.getAdapterPosition(), setting);
+            } catch (CPDFDocumentException e) {
+                e.printStackTrace();
+            }
+        });
+
+        holder.hintIcon.setOnClickListener(view -> {
+            holder.deleteView.setVisibility(View.VISIBLE);
+            holder.item.smoothScrollX(holder.deleteViewOffset);
+        });
+
+        holder.deleteView.setOnClickListener(view -> {
+            holder.item.smoothScrollX(0);
+            holder.deleteView.setVisibility(View.INVISIBLE);
+
+            MainActivity activity = (MainActivity) console.getActivity();
+            assert activity != null;
+
+            try {
+                activity.deleteWatermark(holder.getAdapterPosition());
+            } catch (CPDFDocumentException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+
+    @Override
+    public int getItemCount() {
+        return settings.size();
+    }
+
+    public void updateSettingList(int index, WatermarkSetting setting) {
+        settings.set(index, setting);
+        notifyItemChanged(index);
+    }
+
+    public void addSettingIntoList(WatermarkSetting setting) {
+        settings.add(setting);
+        notifyItemChanged(settings.size());
+    }
+
+    public void deleteSettingFromList(int index) {
+        settings.remove(index);
+        notifyItemRemoved(index);
+    }
+
+    public static class WatermarkItemHolder extends RecyclerView.ViewHolder {
+        int deleteViewOffset;
+
+        WatermarkListItem item;
+        ImageView hintIcon;
+        View deleteView;
+
+        public WatermarkItemHolder(@NonNull View itemView) {
+            super(itemView);
+            item = itemView.findViewById(R.id.item_view);
+            hintIcon = item.findViewById(R.id.hint_icon);
+            deleteView = itemView.findViewById(R.id.delete_view);
+
+//            self = itemView;
+//            this.itemView = itemView.findViewById(R.id.item_view);
+//            deleteView = itemView.findViewById(R.id.delete_view);
+            deleteView.post(() -> deleteViewOffset = deleteView.getWidth());
+            deleteView.setVisibility(View.INVISIBLE);
+//
+//            watermarkType = itemView.findViewById(R.id.watermark_type_icon);
+//            watermarkContent = itemView.findViewById(R.id.watermark_content);
+        }
+    }
+}

+ 0 - 4
app/src/main/java/com/compdfkit/pdfviewer/builder/WatermarkBuilder.java

@@ -1,4 +0,0 @@
-package com.compdfkit.pdfviewer.builder;
-
-public class WatermarkBuilder {
-}

+ 99 - 0
app/src/main/java/com/compdfkit/pdfviewer/customview/WatermarkListItem.java

@@ -0,0 +1,99 @@
+package com.compdfkit.pdfviewer.customview;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.Scroller;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.compdfkit.pdfviewer.R;
+
+public class WatermarkListItem extends ConstraintLayout {
+    private Context currentContext;
+    private LayoutInflater inflater;
+    private View currentView;
+
+    private ImageView watermarkType;
+    private TextView watermarkContent;
+
+    private Scroller mScroller;
+
+    private int deleteOffset = 0;
+
+    public WatermarkListItem(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public WatermarkListItem(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public WatermarkListItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public WatermarkListItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        init(context, attrs);
+    }
+
+//    public WatermarkListItem(@NonNull Context context, ) {
+//
+//    }
+
+    @Override
+    public void computeScroll() {
+        super.computeScroll();
+        if (mScroller.computeScrollOffset()) {
+            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
+            invalidate();
+        }
+    }
+
+    private void init(Context context, AttributeSet attrs) {
+        mScroller = new Scroller(context);
+
+        currentContext = context;
+        inflater = (LayoutInflater) currentContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+        currentView = inflater.inflate(R.layout.watermark_item, this, true);
+
+        watermarkType = currentView.findViewById(R.id.watermark_type_icon);
+        watermarkContent = currentView.findViewById(R.id.watermark_content);
+    }
+
+    public void smoothScrollX(int destX) {
+        int scrollX = getScrollX();
+        int deltaX = destX - scrollX;
+        mScroller.startScroll(scrollX, 0, deltaX, 0, 500);
+        invalidate();
+    }
+
+//    public void showDeleteView() {
+//        smoothScrollX(deleteOffset);
+//    }
+//
+//    public void closeDeleteView() {
+//        smoothScrollX(-deleteOffset);
+//    }
+
+    public void setWatermarkTypeIcon(Drawable drawable) {
+        watermarkType.setImageDrawable(drawable);
+    }
+
+    public void setWatermarkContentText(String text) {
+        watermarkContent.setText(text);
+    }
+
+    @Override
+    public boolean performClick() {
+        return super.performClick();
+    }
+}

+ 18 - 0
app/src/main/java/com/compdfkit/pdfviewer/customview/WatermarkListView.java

@@ -0,0 +1,18 @@
+package com.compdfkit.pdfviewer.customview;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+public class WatermarkListView extends RecyclerView {
+    int lastX = 0;
+    int lastY = 0;
+
+    public WatermarkListView(@NonNull Context context) {
+        super(context);
+    }
+}
+

+ 0 - 98
app/src/main/java/com/compdfkit/pdfviewer/customview/WatermarkView.java

@@ -1,98 +0,0 @@
-package com.compdfkit.pdfviewer.customview;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageButton;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-import com.compdfkit.pdfviewer.entity.WatermarkSetting;
-
-public class WatermarkView extends ConstraintLayout {
-    protected Context currentContext;
-    protected LayoutInflater inflater;
-    protected View currentView;
-    protected ImageButton rollingHandle;
-
-    protected float rotationRadian = 0;
-    protected float sizeConvertRate = 0;
-
-    protected float PDFXOffset = 0;
-    protected float PDFYOffset = 0;
-
-    public static int DRAG_EVENT = 0;
-    public static int ROLL_EVENT = 1;
-
-    //TODO:Try to change the event select.
-    protected int currentEvent = 0;
-
-    public WatermarkView(@NonNull Context context) {
-        this(context, null);
-    }
-
-    public WatermarkView(@NonNull Context context, @Nullable AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public WatermarkView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public WatermarkView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public void setRollingHandle() {}
-
-    public void setRotationRadian(float rotationRadian) {
-        this.rotationRadian = rotationRadian;
-    }
-
-    public float getRotationRadian() {
-        return rotationRadian;
-    }
-
-    public void setWatermarkOpacity(float opacity) {}
-
-    public void setWatermarkScale(float scale) {}
-
-    public void setTextWatermarkColor(int color) {}
-
-    public WatermarkSetting completeSetting(WatermarkSetting setting) {
-        return setting;
-    }
-
-    public int getCurrentEvent() {
-        return currentEvent;
-    }
-
-    public float getPDFXOffset() {
-        return PDFXOffset;
-    }
-
-    public void setPDFXOffset(float PDFXOffset) {
-        this.PDFXOffset = PDFXOffset;
-    }
-
-    public float getPDFYOffset() {
-        return PDFYOffset;
-    }
-
-    public void setPDFYOffset(float PDFYOffset) {
-        this.PDFYOffset = PDFYOffset;
-    }
-
-    public float getSizeConvertRate() {
-        return sizeConvertRate;
-    }
-
-    public void setSizeConvertRate(float sizeConvertRate) {
-        this.sizeConvertRate = sizeConvertRate;
-    }
-
-}

+ 26 - 11
app/src/main/java/com/compdfkit/pdfviewer/customview/ImageWatermarkView.java

@@ -1,9 +1,8 @@
-package com.compdfkit.pdfviewer.customview;
+package com.compdfkit.pdfviewer.customview.watermarkview;
 
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
@@ -14,7 +13,6 @@ import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.Toast;
 
@@ -30,6 +28,8 @@ public class ImageWatermarkView extends WatermarkView {
 
     private Bitmap initBitmap;
 
+    private Bitmap resizeBitmap;
+
     public ImageWatermarkView(@NonNull Context context) {
         this(context, null);
     }
@@ -51,7 +51,6 @@ public class ImageWatermarkView extends WatermarkView {
         currentContext = context;
         inflater = (LayoutInflater) currentContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-        TypedArray attribute = currentContext.obtainStyledAttributes(attrs, R.styleable.WatermarkView);
         currentView = inflater.inflate(R.layout.watermark_image_view, this, true);
 
         watermarkImage = currentView.findViewById(R.id.image_watermark);
@@ -62,6 +61,8 @@ public class ImageWatermarkView extends WatermarkView {
             Canvas canvas = new Canvas(initBitmap);
             drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
             drawable.draw(canvas);
+
+            resizeBitmap = Bitmap.createBitmap(initBitmap, 0, 0, initBitmap.getWidth(), initBitmap.getHeight());
         });
 
         rollingHandle = currentView.findViewById(R.id.watermark_i_handle);
@@ -88,7 +89,6 @@ public class ImageWatermarkView extends WatermarkView {
             currentEvent = 0;
             return true;
         });
-
         setRollingHandle();
     }
 
@@ -119,19 +119,21 @@ public class ImageWatermarkView extends WatermarkView {
 
     @Override
     public void setWatermarkScale(float scale) {
+        setScale(scale);
         Matrix matrix = new Matrix();
         matrix.postScale(scale, scale);
-        Bitmap resizeBmp = Bitmap.createBitmap(initBitmap, 0, 0, initBitmap.getWidth(), initBitmap.getHeight(), matrix, true);
+        resizeBitmap = Bitmap.createBitmap(initBitmap, 0, 0, initBitmap.getWidth(), initBitmap.getHeight(), matrix, true);
 
-        watermarkImage.setImageBitmap(resizeBmp);
+        setWatermarkImageContent(resizeBitmap);
     }
 
     @Override
     public WatermarkSetting completeSetting(WatermarkSetting setting) {
         Matrix matrix = new Matrix();
         matrix.postScale(1 / sizeConvertRate, 1 / sizeConvertRate);
-        Bitmap resultBitmap = Bitmap.createBitmap(initBitmap, 0, 0, initBitmap.getWidth(), initBitmap.getHeight(), matrix, true);
+        Bitmap resultBitmap = Bitmap.createBitmap(resizeBitmap, 0, 0, resizeBitmap.getWidth(), resizeBitmap.getHeight(), matrix, true);
 
+        setting.setType(1);
         setting.setImage(resultBitmap);
         setting.setiWidth(resultBitmap.getWidth());
         setting.setiHeight(resultBitmap.getHeight());
@@ -146,13 +148,26 @@ public class ImageWatermarkView extends WatermarkView {
         super.setSizeConvertRate(sizeConvertRate);
     }
 
+    public void setWatermarkImageContent(Bitmap content) {
+        watermarkImage.setImageBitmap(content);
+//        initBitmap = content;
+    }
+
     public void setWatermarkImageFromPath(String imagePath) {
         if (imagePath != null) {
-            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
-            initBitmap = bitmap;
-            watermarkImage.setImageBitmap(bitmap);
+            initBitmap = BitmapFactory.decodeFile(imagePath);
+            setWatermarkScale(getScale());
         } else {
             Toast.makeText(currentContext, "获取图片失败", Toast.LENGTH_SHORT).show();
         }
     }
+
+    @Override
+    public Bitmap getFullScreenBitmap(int width, int height, int hSpace, int vSpace, int xOffset, int yOffset, float rotation) {
+        Matrix matrix = new Matrix();
+        matrix.setScale(getScale(), getScale());
+
+        Bitmap tempBitmap = Bitmap.createBitmap(initBitmap, 0, 0, initBitmap.getWidth(), initBitmap.getHeight(), matrix, true);
+        return generateFullScreenBitmap(tempBitmap, width, height, hSpace, vSpace, xOffset, yOffset, rotation);
+    }
 }

+ 55 - 15
app/src/main/java/com/compdfkit/pdfviewer/customview/TextWatermarkView.java

@@ -1,9 +1,12 @@
-package com.compdfkit.pdfviewer.customview;
+package com.compdfkit.pdfviewer.customview.watermarkview;
 
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Context;
-import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
 import android.os.Build;
 import android.text.Editable;
 import android.text.TextWatcher;
@@ -30,6 +33,8 @@ public class TextWatermarkView extends WatermarkView{
 
     private float textDefaultSize = 123;
 
+    private static final float verticalOffsetCompensate = 2.6966689f;
+
     public TextWatermarkView(@NonNull Context context) {
         this(context, null);
     }
@@ -101,8 +106,8 @@ public class TextWatermarkView extends WatermarkView{
 
         editText.setText(watermarkText.getText());
         AlertDialog.Builder inputDialog = new AlertDialog.Builder(currentContext);
-        inputDialog.setTitle("Text watermark").setView(textEditorLayout);
-        inputDialog.setPositiveButton("Done", (dialogInterface, i) -> watermarkText.setText(editText.getText().toString()));
+        inputDialog.setTitle(R.string.text_watermark).setView(textEditorLayout);
+        inputDialog.setPositiveButton(R.string.done, (dialogInterface, i) -> setWatermarkTextContent(editText.getText().toString()));
 
         editText.addTextChangedListener(new TextWatcher() {
             @Override
@@ -117,7 +122,7 @@ public class TextWatermarkView extends WatermarkView{
             }
         });
 
-        inputDialog.setNegativeButton("Cancle", (dialogInterface, i) -> {});
+        inputDialog.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {});
 
         AlertDialog dialog = inputDialog.create();
         dialog.show();
@@ -129,16 +134,16 @@ public class TextWatermarkView extends WatermarkView{
     @Override
     public void setRollingHandle() {
         rollingHandle.setOnTouchListener((View view, MotionEvent motionEvent) -> {
-                currentEvent = 1;
-                ClipData.Item item = new ClipData.Item((CharSequence) view.getTag());
-                ClipData dragData = new ClipData(
-                        (CharSequence) view.getTag(),
-                        new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN },
-                        item);
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                    view.startDragAndDrop(dragData, new DragShadowBuilder(rollingHandle), null, 0);     //自定义DragShadowBuilder
-                }
-                return true;
+            currentEvent = 1;
+            ClipData.Item item = new ClipData.Item((CharSequence) view.getTag());
+            ClipData dragData = new ClipData(
+                    (CharSequence) view.getTag(),
+                    new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN },
+                    item);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                view.startDragAndDrop(dragData, new DragShadowBuilder(rollingHandle), null, 0);     //自定义DragShadowBuilder
+            }
+            return true;
         });
     }
 
@@ -149,6 +154,7 @@ public class TextWatermarkView extends WatermarkView{
 
     @Override
     public void setWatermarkScale(float scale) {
+        setScale(scale);
         watermarkText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textDefaultSize * scale);
     }
 
@@ -157,6 +163,14 @@ public class TextWatermarkView extends WatermarkView{
         watermarkText.setTextColor(color);
     }
 
+    public void setWatermarkTextContent(String content) {
+        watermarkText.setText(content);
+    }
+
+    public void setWatermarkTextFontSize(float textFontSize) {
+        watermarkText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textFontSize * sizeConvertRate);
+    }
+
     public void setTextDefaultSize(float textDefaultSize) {
         this.textDefaultSize = textDefaultSize;
         watermarkText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textDefaultSize);
@@ -165,9 +179,11 @@ public class TextWatermarkView extends WatermarkView{
 
     @Override
     public WatermarkSetting completeSetting(WatermarkSetting setting) {
+        setting.setType(0);
         setting.setHorizOffset(getPDFXOffset());
         setting.setVertOffset(getPDFYOffset());
         setting.setText(watermarkText.getText().toString());
+        setting.setFontSize(textDefaultSize / sizeConvertRate * scale);
         setting.setTextRGBColor(watermarkText.getCurrentTextColor());
         setting.setRotation(rotationRadian);
         return setting;
@@ -178,4 +194,28 @@ public class TextWatermarkView extends WatermarkView{
         super.setSizeConvertRate(sizeConvertRate);
         setTextDefaultSize(sizeConvertRate * 62);
     }
+
+    @Override
+    public Bitmap getFullScreenBitmap(int width, int height, int hSpace, int vSpace, int xOffset, int yOffset, float rotation) {
+        Paint paint = new Paint();
+        paint.setTextSize(textDefaultSize);
+        paint.setTextAlign(Paint.Align.LEFT);
+        paint.setColor(watermarkText.getCurrentTextColor());
+
+        Paint.FontMetricsInt fm = paint.getFontMetricsInt();
+
+        int textwidth = (int)paint.measureText((String) watermarkText.getText());
+        int textheight = fm.descent - fm.ascent;
+
+        Bitmap bitmap = Bitmap.createBitmap(textwidth, textheight, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+        canvas.drawText((String) watermarkText.getText(), 0, fm.leading - fm.ascent + 5, paint);
+        canvas.save();
+
+        Matrix matrix = new Matrix();
+        matrix.setScale(getScale(), getScale());
+        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+
+        return generateFullScreenBitmap(bitmap, width, height, hSpace, vSpace, xOffset, yOffset, rotation);
+    }
 }

+ 182 - 0
app/src/main/java/com/compdfkit/pdfviewer/customview/watermarkview/WatermarkView.java

@@ -0,0 +1,182 @@
+package com.compdfkit.pdfviewer.customview.watermarkview;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageButton;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.compdfkit.pdfviewer.entity.WatermarkSetting;
+
+public class WatermarkView extends ConstraintLayout {
+    protected Context currentContext;
+    protected LayoutInflater inflater;
+    protected View currentView;
+    protected ImageButton rollingHandle;
+
+    protected float rotationRadian = 0;
+    protected float sizeConvertRate = 0;
+
+    protected float viewXOffset = 0;
+    protected float viewYOffset = 0;
+
+    protected float PDFXOffset = 0;
+    protected float PDFYOffset = 0;
+
+    protected float scale = 1;
+
+    public static int DRAG_EVENT = 0;
+    public static int ROLL_EVENT = 1;
+
+    //TODO:Try to change the event select.
+    protected int currentEvent = 0;
+
+    public WatermarkView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public WatermarkView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public WatermarkView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public WatermarkView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public void setRollingHandle() {}
+
+    public void setRotationRadian(float rotationRadian) {
+        this.rotationRadian = rotationRadian;
+    }
+
+    public float getRotationRadian() {
+        return rotationRadian;
+    }
+
+    public void setWatermarkOpacity(float opacity) {}
+
+    public void setWatermarkScale(float scale) {}
+
+    public void setTextWatermarkColor(int color) {}
+
+    public WatermarkSetting completeSetting(WatermarkSetting setting) {
+        return setting;
+    }
+
+    public int getCurrentEvent() {
+        return currentEvent;
+    }
+
+    public float getViewXOffset() {
+        return viewXOffset;
+    }
+
+    public void setViewXOffset(float viewXOffset) {
+        this.viewXOffset = viewXOffset;
+    }
+
+    public float getViewYOffset() {
+        return viewYOffset;
+    }
+
+    public void setViewYOffset(float viewYOffset) {
+        this.viewYOffset = viewYOffset;
+    }
+
+    public float getPDFXOffset() {
+        return PDFXOffset;
+    }
+
+    public void setPDFXOffset(float PDFXOffset) {
+        this.PDFXOffset = PDFXOffset;
+    }
+
+    public float getPDFYOffset() {
+        return PDFYOffset;
+    }
+
+    public void setPDFYOffset(float PDFYOffset) {
+        this.PDFYOffset = PDFYOffset;
+    }
+
+    public float getScale() {
+        return scale;
+    }
+
+    public void setScale(float scale) {
+        this.scale = scale;
+    }
+
+    public float getSizeConvertRate() {
+        return sizeConvertRate;
+    }
+
+    public void setSizeConvertRate(float sizeConvertRate) {
+        this.sizeConvertRate = sizeConvertRate;
+    }
+
+    //TODO:有待优化
+    public Bitmap generateFullScreenBitmap(Bitmap srcBitmap, int width, int height, int hSpace, int vSpace, int xOffset, int yOffset, float rotation) {
+        int srcWidth = srcBitmap.getWidth();
+        int srcHeight = srcBitmap.getHeight();
+
+        int longer = Math.max(width, height);
+
+        int xTimes = longer * 2 / (srcWidth + hSpace);
+        int yTimes = longer * 2 / (srcHeight + vSpace);
+
+        int centerX = width / 2;
+        int centerY = height / 2;
+
+        int centerXOffset = centerX % (srcWidth + hSpace) - (srcWidth + hSpace) / 2;
+        int centerYOffset = centerY % (srcHeight + vSpace) - (srcHeight + vSpace) / 2;
+
+        int originXOffset = xOffset;
+        int originYOffset = yOffset;
+
+        xOffset = xOffset % (srcWidth + hSpace);
+        yOffset = yOffset % (srcHeight + vSpace);
+
+        Matrix matrix = new Matrix();
+
+        Bitmap bitmap = Bitmap.createBitmap(longer * 2, longer * 2, Bitmap.Config.ARGB_4444);
+        Canvas canvas = new Canvas(bitmap);
+
+        int paintOffsetX = (srcWidth + hSpace) - (((bitmap.getWidth() - width) / 2) % (srcWidth + hSpace));
+        int paintOffsetY = (srcHeight + vSpace) - (((bitmap.getHeight() - height) / 2) % (srcHeight + vSpace));
+
+        for (int i = -1; i < xTimes + 1; i++) {
+            for(int j = -1; j < yTimes + 1; j++) {
+                int left = i * (srcWidth + hSpace) + centerXOffset + hSpace / 2  - paintOffsetX;
+                int top = j * (srcHeight + vSpace) + centerYOffset + vSpace / 2 - paintOffsetY;
+
+                canvas.drawBitmap(srcBitmap, left, top, null);
+            }
+        }
+
+        matrix.setTranslate(longer, longer);
+        matrix.postTranslate(xOffset, -yOffset);
+        matrix.postRotate(rotation, 2 * longer + originXOffset, 2 *longer - originYOffset);
+
+        Bitmap testBitmap = Bitmap.createBitmap(bitmap.getWidth() * 2, bitmap.getHeight() * 2, Bitmap.Config.ARGB_4444);
+        Canvas testCanvas = new Canvas(testBitmap);
+        testCanvas.drawBitmap(bitmap, matrix, null);
+
+        return Bitmap.createBitmap(testBitmap, (testBitmap.getWidth() - width) / 2, (testBitmap.getHeight() - height) / 2, width, height);
+    }
+
+    public Bitmap getFullScreenBitmap(int width, int height, int hSpace, int vSpace, int xOffset, int yOffset, float rotation) {
+        return generateFullScreenBitmap(null, width, height, hSpace, vSpace, xOffset, yOffset, rotation);
+    }
+}

+ 13 - 2
app/src/main/java/com/compdfkit/pdfviewer/entity/WatermarkSetting.java

@@ -3,6 +3,8 @@ package com.compdfkit.pdfviewer.entity;
 import android.graphics.Bitmap;
 
 public class WatermarkSetting {
+    private int type;
+
     private Bitmap image;
     private int iWidth;
     private int iHeight;
@@ -23,6 +25,8 @@ public class WatermarkSetting {
     private int textRGBColor;
 
     public WatermarkSetting() {
+        type = 0;
+
         image = null;
         iWidth = 0;
         iHeight = 0;
@@ -47,6 +51,14 @@ public class WatermarkSetting {
         return image;
     }
 
+    public int getType() {
+        return type;
+    }
+
+    public void setType(int type) {
+        this.type = type;
+    }
+
     public void setImage(Bitmap image) {
         this.image = image;
     }
@@ -80,8 +92,7 @@ public class WatermarkSetting {
     }
 
     public void setFontSize(float fontSize) {
-        float conversionRate = 0.504f;
-        this.fontSize = fontSize * conversionRate;
+        this.fontSize = fontSize;
     }
 
     public boolean isFront() {

+ 132 - 7
app/src/main/java/com/compdfkit/pdfviewer/fragments/WatermarkConsoleFragment.java

@@ -9,6 +9,8 @@ import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
 import android.net.Uri;
 import android.os.Bundle;
 
@@ -35,9 +37,12 @@ import android.view.ViewGroup;
 import android.widget.CheckBox;
 import android.widget.TextView;
 
+import com.compdfkit.core.common.CPDFDocumentException;
+import com.compdfkit.pdfviewer.MainActivity;
 import com.compdfkit.pdfviewer.R;
-import com.compdfkit.pdfviewer.customview.ImageWatermarkView;
-import com.compdfkit.pdfviewer.customview.WatermarkView;
+import com.compdfkit.pdfviewer.customview.watermarkview.ImageWatermarkView;
+import com.compdfkit.pdfviewer.customview.watermarkview.TextWatermarkView;
+import com.compdfkit.pdfviewer.customview.watermarkview.WatermarkView;
 import com.compdfkit.pdfviewer.entity.WatermarkSetting;
 import com.google.android.material.textfield.TextInputEditText;
 
@@ -53,6 +58,13 @@ public class WatermarkConsoleFragment extends Fragment {
     private int iWatermarkOpacity = 50;
     private int iWatermarkSize = 50;
 
+    private int documentPageCount = 0;
+
+    private float currentOpacity = 0.5f;
+
+    private float hSpace = 100f;
+    private float vSpace = 100f;
+
     private final WatermarkSetting setting = new WatermarkSetting();
 
     private WatermarkView associatedWatermark = null;
@@ -133,6 +145,7 @@ public class WatermarkConsoleFragment extends Fragment {
 
         hSpaceEdit = returnView.findViewById(R.id.horizontal_space);
         vSpaceEdit = returnView.findViewById(R.id.vertical_space);
+        initSpaceEdits();
     }
 
     private void initColorPicker(View returnView) {
@@ -212,6 +225,7 @@ public class WatermarkConsoleFragment extends Fragment {
             @SuppressLint("SetTextI18n")
             @Override
             public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+                currentOpacity = i / 100f;
                 if (mode == 0)
                     tWatermarkOpacity = i;
                 else
@@ -240,7 +254,6 @@ public class WatermarkConsoleFragment extends Fragment {
 
                 i = i + 50;
                 sizeText.setText(i + "%");
-                setting.setScale(1.0f * i / 100);
                 associatedWatermark.setWatermarkScale(1.0f * i / 100);
             }
             @Override
@@ -265,19 +278,20 @@ public class WatermarkConsoleFragment extends Fragment {
                 rangeEditText.setText(pageRange);
 
             AlertDialog.Builder inputDialog = new AlertDialog.Builder(getActivity());
-            inputDialog.setTitle("Text watermark").setView(rangeSelectLayout);
-            inputDialog.setPositiveButton("Done", (dialogInterface, i) -> {
+            inputDialog.setTitle(R.string.setting_range).setView(rangeSelectLayout);
+            inputDialog.setPositiveButton(R.string.done, (dialogInterface, i) -> {
                 if (customRadioBtn.isChecked()) {
                     pageRange = Objects.requireNonNull(rangeEditText.getText()).toString();
                     rangeMsg.setText(pageRange);
                 } else {
                     //TODO: Repair the code to set All pages range
-                    rangeMsg.setText("All pages");
+                    rangeMsg.setText(R.string.all_pages);
+                    pageRange = "0-" + (documentPageCount - 1);
                 }
                 isCustomRange = customRadioBtn.isChecked();
             });
 
-            inputDialog.setNegativeButton("Cancel", (dialogInterface, i) -> {});
+            inputDialog.setNegativeButton(R.string.cancel, (dialogInterface, i) -> {});
 
             customRadioBtn.setOnCheckedChangeListener((compoundButton, b) -> {
                 rangeEditText.setEnabled(b);
@@ -305,6 +319,8 @@ public class WatermarkConsoleFragment extends Fragment {
     }
 
     private void initFullScreenCheck() {
+        MainActivity activity = (MainActivity) getActivity();
+
         fullScreenCheck.setOnCheckedChangeListener((compoundButton, b) -> {
             boolean isFullScreen = fullScreenCheck.isChecked();
 
@@ -313,6 +329,37 @@ public class WatermarkConsoleFragment extends Fragment {
 
             hSpaceEdit.setEnabled(isFullScreen);
             vSpaceEdit.setEnabled(isFullScreen);
+
+            assert activity != null;
+            activity.showFullScreenMask(b);
+
+//            associatedWatermark.setVisibility(b ? View.INVISIBLE : View.VISIBLE);
+        });
+    }
+
+    private void initSpaceEdits() {
+        hSpaceEdit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View view, boolean b) {
+                if (!b) {
+                    sethSpace(Float.parseFloat(Objects.requireNonNull(hSpaceEdit.getText()).toString()));
+                    MainActivity activity = (MainActivity) getActivity();
+                    assert activity != null;
+                    activity.showFullScreenMask(true);
+                }
+            }
+        });
+
+        vSpaceEdit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View view, boolean b) {
+                if (!b) {
+                    setvSpace(Float.parseFloat(Objects.requireNonNull(vSpaceEdit.getText()).toString()));
+                    MainActivity activity = (MainActivity) getActivity();
+                    assert activity != null;
+                    activity.showFullScreenMask(true);
+                }
+            }
         });
     }
 
@@ -325,8 +372,14 @@ public class WatermarkConsoleFragment extends Fragment {
         colorPicker.setVisibility(this.mode == 0 ? View.VISIBLE : View.INVISIBLE);
         imagePicker.setVisibility(this.mode == 0 ? View.INVISIBLE : View.VISIBLE);
 
+        currentOpacity = (this.mode == 0 ? tWatermarkOpacity : iWatermarkOpacity) / 100.0f;
         opacitySlider.setProgress(this.mode == 0 ? tWatermarkOpacity : iWatermarkOpacity);
         sizeSlider.setProgress(this.mode == 0 ? tWatermarkSize : iWatermarkSize);
+        if (fullScreenCheck.isChecked()) {
+            MainActivity activity = (MainActivity) getActivity();
+            assert activity != null;
+            activity.showFullScreenMask(true);
+        }
     }
 
     public WatermarkSetting getWatermarkSetting() {
@@ -340,8 +393,80 @@ public class WatermarkConsoleFragment extends Fragment {
         return setting;
     }
 
+    public float getCurrentOpacity() {
+        return currentOpacity;
+    }
+
+    public float gethSpace() {
+        return Float.parseFloat(Objects.requireNonNull(hSpaceEdit.getText()).toString());
+    }
+
+    public void sethSpace(float hSpace) {
+        this.hSpace = hSpace;
+    }
+
+    public float getvSpace() {
+        return Float.parseFloat(Objects.requireNonNull(vSpaceEdit.getText()).toString());
+    }
+
+    public void setvSpace(float vSpace) {
+        this.vSpace = vSpace;
+    }
+
     public int getMode() {
         return mode;
     }
+
+    public void setDocumentPageCount(int count) {
+        this.documentPageCount = count;
+        pageRange = "0-" + (count - 1);
+    }
+
+    public void resetWatermarkFromSetting(int index, WatermarkSetting setting) throws CPDFDocumentException {
+        MainActivity activity = (MainActivity) getActivity();
+        assert activity != null;
+
+        activity.closeWatermarkList();
+        activity.hideWatermark(index);
+
+        activity.changeWatermark(setting.getType());
+
+        if (mode == 0) {
+            TextWatermarkView temp = (TextWatermarkView) associatedWatermark;
+            temp.setWatermarkTextContent(setting.getText());
+            temp.setTextWatermarkColor(setting.getTextRGBColor());
+            temp.setWatermarkTextFontSize(setting.getFontSize());
+        } else {
+            ImageWatermarkView temp = (ImageWatermarkView) associatedWatermark;
+            Bitmap settingBitmap = setting.getImage();
+            Matrix matrix = new Matrix();
+            matrix.postScale(temp.getSizeConvertRate(), temp.getSizeConvertRate());
+
+            settingBitmap = Bitmap.createBitmap(settingBitmap, 0, 0, settingBitmap.getWidth(), settingBitmap.getHeight(), matrix, true);
+
+            temp.setWatermarkImageContent(settingBitmap);
+        }
+
+        associatedWatermark.setWatermarkOpacity(setting.getOpacity());
+        opacitySlider.setProgress((int) (setting.getOpacity() * 100));
+
+        associatedWatermark.setRotationRadian(setting.getRotation());
+        associatedWatermark.setRotation((float) -Math.toDegrees(setting.getRotation()));
+
+        activity.changeWatermarkLocation(setting.getHorizOffset(), setting.getVertOffset());
+
+        fullScreenCheck.setChecked(setting.getFullScreen());
+        hSpaceEdit.setText(String.valueOf(setting.getHorizontalSpacing()));
+        vSpaceEdit.setText(String.valueOf(setting.getVerticalSpacing()));
+
+        isCustomRange = !setting.getPages().equals("0-" + (documentPageCount - 1));
+        pageRange = setting.getPages();
+
+        if (isCustomRange) {
+            rangeMsg.setText(pageRange);
+        } else {
+            rangeMsg.setText(R.string.all_pages);
+        }
+    }
 }
 

+ 27 - 0
app/src/main/java/com/compdfkit/pdfviewer/tools/ConvertMapper.java

@@ -0,0 +1,27 @@
+package com.compdfkit.pdfviewer.tools;
+
+public class ConvertMapper {
+    public static float convertViewXToPDFXOffset(float viewX, float xOffset, float centerX, float convertRate) {
+        return (viewX + xOffset - centerX) / convertRate;
+    }
+
+    public static float convertViewYToPDFYOffset(float viewY, float yOffset, float centerY, float convertRate) {
+        return (centerY - (viewY + yOffset)) / convertRate;
+    }
+
+    public static float convertPDFXOffsetToViewX(float PDFX, float xOffset, float centerX, float convertRate) {
+        return PDFX * convertRate + centerX - xOffset;
+    }
+
+    public static float convertPDFYOffsetToViewY(float PDFY, float yOffset, float centerY, float convertRate) {
+        return -(PDFY * convertRate + yOffset - centerY);
+    }
+
+    public static float convertMMtoPDFUnit(float mm) {
+        return 72 * mm / 25.4f;
+    }
+
+    public static float convertMMtoViewUnit(float mm, float convertRate) {
+        return convertMMtoPDFUnit(mm) * convertRate * 0.355f;
+    }
+}

+ 0 - 11
app/src/main/java/com/compdfkit/pdfviewer/tools/CoordinateMapper.java

@@ -1,11 +0,0 @@
-package com.compdfkit.pdfviewer.tools;
-
-public class CoordinateMapper {
-    public static float convertViewXtoPDFXOffset(float viewX, float xOffset, float centerX, float convertRate) {
-        return (viewX + xOffset - centerX) / convertRate;
-    }
-
-    public static float convertViewYtoPDFYOffset(float viewY, float yOffset, float centerY, float convertRate) {
-        return (centerY - (viewY + yOffset)) / convertRate;
-    }
-}

+ 87 - 0
app/src/main/java/com/compdfkit/pdfviewer/tools/WatermarkHandle.java

@@ -0,0 +1,87 @@
+package com.compdfkit.pdfviewer.tools;
+
+import com.compdfkit.core.watermark.CPDFWatermark;
+import com.compdfkit.pdfviewer.entity.WatermarkSetting;
+
+import java.util.ArrayList;
+
+public class WatermarkHandle {
+    private static final ArrayList<WatermarkSetting> settingList = new ArrayList<>();
+
+    public static void updateWatermark(CPDFWatermark watermark, WatermarkSetting setting, float sizeConvertRate) {
+        try {
+            if (watermark != null && watermark.isValid()) {
+                if (setting.getImage() != null)
+                    watermark.setImage(setting.getImage(), (int) (setting.getiWidth() * sizeConvertRate), (int) (setting.getiHeight() * sizeConvertRate));
+                watermark.setText(setting.getText());
+                watermark.setFontName(setting.getFontName());
+                watermark.setTextRGBColor(setting.getTextRGBColor());
+                watermark.setOpacity(setting.getOpacity());
+                watermark.setFontSize(setting.getFontSize());
+                watermark.setFront(true);
+                watermark.setVertalign(CPDFWatermark.Vertalign.WATERMARK_VERTALIGN_CENTER);
+                watermark.setHorizalign(CPDFWatermark.Horizalign.WATERMARK_HORIZALIGN_CENTER);
+                watermark.setVertOffset(setting.getVertOffset());
+                watermark.setHorizOffset(setting.getHorizOffset());
+                watermark.setRotation(setting.getRotation());
+                watermark.setScale(setting.getScale());
+                watermark.setPages(setting.getPages());
+                watermark.setFullScreen(setting.getFullScreen());
+                watermark.setHorizontalSpacing(setting.getHorizontalSpacing());
+                watermark.setVerticalSpacing(setting.getVerticalSpacing());
+                watermark.update();
+            }
+        } finally {
+            if (watermark != null && watermark.isValid()) {
+                watermark.release();
+            }
+        }
+    }
+
+    public static WatermarkSetting getSettingFromWatermark(CPDFWatermark watermark) {
+        WatermarkSetting setting = new WatermarkSetting();
+        setting.setType(watermark.getType() == CPDFWatermark.Type.WATERMARK_TYPE_TEXT ? 0 : 1);
+
+        setting.setImage(watermark.getImage());
+        setting.setText(watermark.getText());
+        setting.setFontName(watermark.getFontName());
+        setting.setTextRGBColor(watermark.getTextRGBColor());
+        setting.setOpacity(watermark.getOpacity());
+        setting.setFontSize(watermark.getFontSize());
+        setting.setFront(true);
+        setting.setVertOffset(watermark.getVertOffset());
+        setting.setHorizOffset(watermark.getHorizOffset());
+        setting.setRotation(watermark.getRotation());
+        setting.setScale(watermark.getScale());
+        setting.setPages(watermark.getPages());
+        setting.setFullScreen(watermark.isFullScreen());
+        setting.setHorizontalSpacing(watermark.getHorizontalSpacing());
+        setting.setVerticalSpacing(watermark.getVerticalSpacing());
+
+        return setting;
+    }
+
+    public static void addSettingIntoList(CPDFWatermark watermark) {
+        settingList.add(getSettingFromWatermark(watermark));
+    }
+
+    public static ArrayList<WatermarkSetting> getSettingList() {
+        return settingList;
+    }
+
+    public static WatermarkSetting getSettingFromList(int index) {
+        return settingList.get(index);
+    }
+
+    public static void updateSetting(int index, WatermarkSetting setting) {
+        settingList.set(index, setting);
+    }
+
+    public static void deleteSettingFromList(int index) {
+        settingList.remove(index);
+    }
+
+    public static void clearSettingList() {
+        settingList.clear();
+    }
+}

+ 5 - 0
app/src/main/res/drawable-v31/ic_baseline_done_24.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="?android:attr/textColorPrimary"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable-v31/ic_baseline_edit_note_24.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="?android:attr/textColorPrimary"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M3,10h11v2H3V10zM3,8h11V6H3V8zM3,16h7v-2H3V16zM18.01,12.87l0.71,-0.71c0.39,-0.39 1.02,-0.39 1.41,0l0.71,0.71c0.39,0.39 0.39,1.02 0,1.41l-0.71,0.71L18.01,12.87zM17.3,13.58l-5.3,5.3V21h2.12l5.3,-5.3L17.3,13.58z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable-v31/ic_baseline_format_size_20.xml

@@ -0,0 +1,5 @@
+<vector android:height="20dp" android:tint="?android:attr/textColorPrimary"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="20dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M9,4v3h5v12h3L17,7h5L22,4L9,4zM3,12h3v7h3v-7h3L12,9L3,9v3z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable-v31/ic_baseline_opacity_20.xml

@@ -0,0 +1,5 @@
+<vector android:height="20dp" android:tint="?android:attr/textColorPrimary"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="20dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M17.66,8L12,2.35 6.34,8C4.78,9.56 4,11.64 4,13.64s0.78,4.11 2.34,5.67 3.61,2.35 5.66,2.35 4.1,-0.79 5.66,-2.35S20,15.64 20,13.64 19.22,9.56 17.66,8zM6,14c0.01,-2 0.62,-3.27 1.76,-4.4L12,5.27l4.24,4.38C17.38,10.77 17.99,12 18,14H6z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable-v31/ic_baseline_watermark_add_24.xml

@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="24dp"
+    android:tint="?android:attr/textColorPrimary" android:viewportHeight="24"
+    android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M14,2L6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6zM16,16h-3v3h-2v-3L8,16v-2h3v-3h2v3h3v2zM13,9L13,3.5L18.5,9L13,9z"/>
+</vector>

+ 8 - 0
app/src/main/res/drawable/delete_view.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="#e06666" />
+    <corners
+        android:radius="5dp" />
+</shape>

+ 5 - 0
app/src/main/res/drawable/ic_baseline_delete_forever_24.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#FFFFFF"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8.46,11.88l1.41,-1.41L12,12.59l2.12,-2.12 1.41,1.41L13.41,14l2.12,2.12 -1.41,1.41L12,15.41l-2.12,2.12 -1.41,-1.41L10.59,14l-2.13,-2.12zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable/ic_baseline_edit_note_24.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#FFFFFF"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M3,10h11v2H3V10zM3,8h11V6H3V8zM3,16h7v-2H3V16zM18.01,12.87l0.71,-0.71c0.39,-0.39 1.02,-0.39 1.41,0l0.71,0.71c0.39,0.39 0.39,1.02 0,1.41l-0.71,0.71L18.01,12.87zM17.3,13.58l-5.3,5.3V21h2.12l5.3,-5.3L17.3,13.58z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable/ic_baseline_image_type_24.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#888888"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M21,19V5c0,-1.1 -0.9,-2 -2,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2zM8.5,13.5l2.5,3.01L14.5,12l4.5,6H5l3.5,-4.5z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable/ic_baseline_keyboard_arrow_right_24.xml

@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="24dp"
+    android:tint="#888888" android:viewportHeight="24"
+    android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M8.59,16.59L13.17,12 8.59,7.41 10,6l6,6 -6,6 -1.41,-1.41z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable/ic_baseline_text_type_24.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#888888"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M5,17v2h14v-2L5,17zM9.5,12.8h5l0.9,2.2h2.1L12.75,4h-1.5L6.5,15h2.1l0.9,-2.2zM12,5.98L13.87,11h-3.74L12,5.98z"/>
+</vector>

+ 5 - 0
app/src/main/res/drawable/ic_baseline_watermark_add_24.xml

@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="24dp"
+    android:tint="#FFFFFF" android:viewportHeight="24"
+    android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M14,2L6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6zM16,16h-3v3h-2v-3L8,16v-2h3v-3h2v3h3v2zM13,9L13,3.5L18.5,9L13,9z"/>
+</vector>

+ 8 - 0
app/src/main/res/drawable/watermark_item_light.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="#ffffff" />
+    <corners
+        android:radius="5dp" />
+</shape>

+ 134 - 0
app/src/main/res/layout-land-v31/activity_main.xml

@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="30dp"
+        android:minHeight="?actionBarSize"
+        android:elevation="4dp"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:title="@string/add_watermark"/>
+
+    <com.google.android.material.tabs.TabLayout
+        android:id="@+id/tab_layout"
+        android:layout_width="match_parent"
+        android:layout_height="30dp"
+        app:tabTextAppearance="@style/TabLayoutTextStyle"
+        app:layout_constraintTop_toBottomOf="@+id/toolbar"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <com.google.android.material.tabs.TabItem
+            android:id="@+id/text_item"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/text"
+            tools:layout_editor_absoluteX="164dp"
+            tools:layout_editor_absoluteY="52dp" />
+
+        <com.google.android.material.tabs.TabItem
+            android:id="@+id/image_item"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/image"
+            tools:layout_editor_absoluteX="164dp"
+            tools:layout_editor_absoluteY="52dp" />
+
+    </com.google.android.material.tabs.TabLayout>
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/page_image"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/console_view"
+        android:contentDescription="@string/page_image" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/full_screen_mask"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/console_view"
+        android:contentDescription="@string/full_screen_mask" />
+
+    <com.compdfkit.pdfviewer.customview.watermarkview.TextWatermarkView
+        android:id="@+id/watermark_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="@id/page_image"
+        app:layout_constraintBottom_toBottomOf="@id/page_image"
+        app:layout_constraintEnd_toEndOf="@id/page_image"
+        app:layout_constraintStart_toStartOf="@id/page_image"
+        app:image_mode="false" />
+
+    <com.compdfkit.pdfviewer.customview.watermarkview.ImageWatermarkView
+        android:id="@+id/watermark_image"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible"
+        app:layout_constraintTop_toTopOf="@id/page_image"
+        app:layout_constraintBottom_toBottomOf="@id/page_image"
+        app:layout_constraintEnd_toEndOf="@id/page_image"
+        app:layout_constraintStart_toStartOf="@id/page_image"
+        app:image_mode="false" />
+
+    <androidx.appcompat.widget.AppCompatImageButton
+        android:layout_margin="10dp"
+        android:id="@+id/expand_list_btn"
+        android:backgroundTint="@color/white"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible"
+        android:elevation="4dp"
+        app:srcCompat="@drawable/ic_baseline_keyboard_arrow_right_24"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/watermark_list"
+        android:layout_width="160dp"
+        android:layout_height="0dp"
+        android:background="@color/gray"
+        android:elevation="4dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <View
+        android:id="@+id/divider2"
+        android:layout_width="1dp"
+        android:layout_height="0dp"
+        android:background="?android:attr/listDivider"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/console_view"/>
+
+    <androidx.fragment.app.FragmentContainerView
+        android:name="com.compdfkit.pdfviewer.fragments.WatermarkConsoleFragment"
+        android:id="@+id/console_view"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:elevation="4dp"
+        android:tag="console_fragment"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        tools:layout="@layout/fragment_watermark_console" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 346 - 0
app/src/main/res/layout-land-v31/fragment_watermark_console.xml

@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="350dp"
+    android:layout_height="match_parent"
+    android:padding="10dp"
+    android:elevation="4dp"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    tools:context=".fragments.WatermarkConsoleFragment">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/picker"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@+id/opacity_icon"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" >
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/color_picker"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="8dp"
+            android:visibility="visible"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" >
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_selected"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/circle"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_1"
+                app:layout_constraintStart_toStartOf="parent" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_1"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle1_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_2"
+                app:layout_constraintStart_toEndOf="@id/color_selected" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_2"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle2_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_3"
+                app:layout_constraintStart_toEndOf="@id/color_1" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_3"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle3_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_4"
+                app:layout_constraintStart_toEndOf="@id/color_2" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_4"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle4_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_5"
+                app:layout_constraintStart_toEndOf="@id/color_3" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_5"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle5_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_6"
+                app:layout_constraintStart_toEndOf="@id/color_4" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_6"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle6_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_7"
+                app:layout_constraintStart_toEndOf="@id/color_5" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_7"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle7_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toEndOf="@id/color_6" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/image_picker"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="5dp"
+            android:visibility="invisible"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" >
+
+            <TextView
+                android:id="@+id/image_select_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/image"
+                android:textSize="20sp"
+                android:padding="7dp"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent" />
+
+            <TextView
+                android:id="@+id/image_select_path"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:padding="3dp"
+                android:text="@string/default_image"
+                app:layout_constraintTop_toTopOf="@id/image_select_text"
+                app:layout_constraintBottom_toBottomOf="@id/image_select_text"
+                app:layout_constraintStart_toEndOf="@id/image_select_text"
+                app:layout_constraintEnd_toStartOf="@id/image_select_btn" />
+
+            <Button
+                android:id="@+id/image_select_btn"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/select_image"
+                app:layout_constraintTop_toTopOf="@+id/image_select_text"
+                app:layout_constraintBottom_toBottomOf="@id/image_select_text"
+                app:layout_constraintEnd_toEndOf="parent"
+                tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <ImageView
+        android:id="@+id/opacity_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:contentDescription="@string/opacity_icon"
+        android:src="@drawable/ic_baseline_opacity_20"
+        android:padding="10dp"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintEnd_toStartOf="@+id/opacity_slider"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/picker"
+        app:layout_constraintBottom_toTopOf="@+id/size_icon"/>
+
+    <androidx.appcompat.widget.AppCompatSeekBar
+        android:id="@+id/opacity_slider"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:progress="50"
+        android:theme="@style/SeekBarColor"
+        app:layout_constraintTop_toTopOf="@id/opacity_icon"
+        app:layout_constraintBottom_toBottomOf="@id/opacity_icon"
+        app:layout_constraintStart_toEndOf="@+id/opacity_icon"
+        app:layout_constraintEnd_toStartOf="@id/opacity_text"/>
+
+    <TextView
+        android:id="@+id/opacity_text"
+        android:layout_width="40dp"
+        android:layout_height="wrap_content"
+        android:text="@string/default_opacity"
+        app:layout_constraintTop_toTopOf="@id/opacity_icon"
+        app:layout_constraintBottom_toBottomOf="@id/opacity_icon"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/opacity_slider" />
+
+
+    <ImageView
+        android:id="@+id/size_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:contentDescription="@string/opacity_icon"
+        android:src="@drawable/ic_baseline_format_size_20"
+        android:padding="10dp"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintEnd_toStartOf="@+id/size_slider"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/opacity_icon"
+        app:layout_constraintBottom_toTopOf="@+id/page_range_text"/>
+
+    <androidx.appcompat.widget.AppCompatSeekBar
+        android:id="@+id/size_slider"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:progress="50"
+        android:theme="@style/SeekBarColor"
+        app:layout_constraintTop_toTopOf="@id/size_icon"
+        app:layout_constraintBottom_toBottomOf="@id/size_icon"
+        app:layout_constraintStart_toEndOf="@+id/size_icon"
+        app:layout_constraintEnd_toStartOf="@id/size_text"/>
+
+    <TextView
+        android:id="@+id/size_text"
+        android:layout_width="40dp"
+        android:layout_height="wrap_content"
+        android:text="@string/default_scale"
+        app:layout_constraintTop_toTopOf="@id/size_icon"
+        app:layout_constraintBottom_toBottomOf="@id/size_icon"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/size_slider" />
+
+    <TextView
+        android:id="@+id/page_range_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/page_range"
+        android:textSize="20sp"
+        android:padding="12dp"
+        app:layout_constraintTop_toBottomOf="@+id/size_icon"
+        app:layout_constraintBottom_toTopOf="@id/full_screen_checkbox"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <TextView
+        android:id="@+id/page_range_msg"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/all_pages"
+        app:layout_constraintTop_toTopOf="@id/page_range_text"
+        app:layout_constraintBottom_toBottomOf="@id/page_range_text"
+        app:layout_constraintEnd_toStartOf="@id/page_range_button" />
+
+    <ImageButton
+        android:padding="10dp"
+        android:id="@+id/page_range_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#00000000"
+        android:src="@drawable/ic_baseline_expand_more_24"
+        app:layout_constraintBottom_toBottomOf="@id/page_range_text"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@id/page_range_text"/>
+
+
+    <CheckBox
+        android:id="@+id/full_screen_checkbox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="10dp"
+        android:text="@string/full_screen"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/page_range_text"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/full_screen_space"
+        tools:ignore="TouchTargetSizeCheck" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/full_screen_space"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="@id/full_screen_checkbox"
+        app:layout_constraintBottom_toBottomOf="@id/full_screen_checkbox"
+        app:layout_constraintStart_toEndOf="@id/full_screen_checkbox"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:id="@+id/horizontal_space"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:hint="@string/default_space"
+            android:text="@string/default_space"
+            android:enabled="false"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/horizontal_space_mm"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:ignore="TouchTargetSizeCheck,DuplicateSpeakableTextCheck" />
+
+        <TextView
+            android:id="@+id/horizontal_space_mm"
+            android:layout_width="40dp"
+            android:layout_height="wrap_content"
+            android:text="@string/mm"
+            app:layout_constraintTop_toTopOf="@id/horizontal_space"
+            app:layout_constraintBottom_toBottomOf="@id/horizontal_space"
+            app:layout_constraintStart_toEndOf="@+id/horizontal_space"
+            app:layout_constraintEnd_toStartOf="@id/vertical_space"/>
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:id="@+id/vertical_space"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:hint="@string/default_space"
+            android:text="@string/default_space"
+            android:enabled="false"
+            app:layout_constraintBottom_toBottomOf="@id/horizontal_space"
+            app:layout_constraintEnd_toStartOf="@id/vertical_space_mm"
+            app:layout_constraintStart_toEndOf="@id/horizontal_space_mm"
+            app:layout_constraintTop_toTopOf="@id/horizontal_space"
+            tools:ignore="TouchTargetSizeCheck" />
+
+        <TextView
+            android:id="@+id/vertical_space_mm"
+            android:layout_width="40dp"
+            android:layout_height="wrap_content"
+            android:text="@string/mm"
+            app:layout_constraintTop_toTopOf="@id/horizontal_space"
+            app:layout_constraintBottom_toBottomOf="@id/horizontal_space"
+            app:layout_constraintStart_toEndOf="@+id/vertical_space"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 39 - 4
app/src/main/res/layout-land/activity_main.xml

@@ -16,7 +16,7 @@
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:title="Add Watermark"
+        app:title="@string/add_watermark"
         app:titleTextColor="@color/white" />
 
     <com.google.android.material.tabs.TabLayout
@@ -51,7 +51,7 @@
 
     </com.google.android.material.tabs.TabLayout>
 
-    <ImageView
+    <androidx.appcompat.widget.AppCompatImageView
         android:id="@+id/page_image"
         android:layout_width="wrap_content"
         android:layout_height="0dp"
@@ -61,7 +61,18 @@
         app:layout_constraintEnd_toStartOf="@id/console_view"
         android:contentDescription="@string/page_image" />
 
-    <com.compdfkit.pdfviewer.customview.TextWatermarkView
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/full_screen_mask"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/console_view"
+        android:contentDescription="@string/full_screen_mask" />
+
+    <com.compdfkit.pdfviewer.customview.watermarkview.TextWatermarkView
         android:id="@+id/watermark_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -71,7 +82,7 @@
         app:layout_constraintStart_toStartOf="@id/page_image"
         app:image_mode="false" />
 
-    <com.compdfkit.pdfviewer.customview.ImageWatermarkView
+    <com.compdfkit.pdfviewer.customview.watermarkview.ImageWatermarkView
         android:id="@+id/watermark_image"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -82,6 +93,30 @@
         app:layout_constraintStart_toStartOf="@id/page_image"
         app:image_mode="false" />
 
+    <androidx.appcompat.widget.AppCompatImageButton
+        android:layout_margin="10dp"
+        android:id="@+id/expand_list_btn"
+        android:backgroundTint="@color/white"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible"
+        android:elevation="4dp"
+        app:srcCompat="@drawable/ic_baseline_keyboard_arrow_right_24"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/watermark_list"
+        android:layout_width="160dp"
+        android:layout_height="0dp"
+        android:background="@color/gray"
+        android:elevation="4dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
     <androidx.fragment.app.FragmentContainerView
         android:name="com.compdfkit.pdfviewer.fragments.WatermarkConsoleFragment"
         android:id="@+id/console_view"

+ 23 - 10
app/src/main/res/layout-land/fragment_watermark_console.xml

@@ -5,6 +5,7 @@
     android:layout_height="match_parent"
     android:background="@color/white"
     android:padding="10dp"
+    android:elevation="4dp"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     tools:context=".fragments.WatermarkConsoleFragment">
 
@@ -28,7 +29,7 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintEnd_toEndOf="parent" >
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_selected"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
@@ -40,7 +41,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_1"
                 app:layout_constraintStart_toStartOf="parent" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_1"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -52,7 +53,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_2"
                 app:layout_constraintStart_toEndOf="@id/color_selected" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_2"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -64,7 +65,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_3"
                 app:layout_constraintStart_toEndOf="@id/color_1" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_3"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -76,7 +77,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_4"
                 app:layout_constraintStart_toEndOf="@id/color_2" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_4"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -88,7 +89,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_5"
                 app:layout_constraintStart_toEndOf="@id/color_3" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_5"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -100,7 +101,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_6"
                 app:layout_constraintStart_toEndOf="@id/color_4" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_6"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -112,7 +113,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_7"
                 app:layout_constraintStart_toEndOf="@id/color_5" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_7"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -164,7 +165,7 @@
                 android:id="@+id/image_select_btn"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="Select"
+                android:text="@string/select_image"
                 android:textColor="@color/white"
                 android:backgroundTint="@color/purple_500"
                 app:layout_constraintTop_toTopOf="@+id/image_select_text"
@@ -267,11 +268,23 @@
 <!--        app:layout_constraintTop_toTopOf="@id/page_range_text"-->
 <!--        tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />-->
 
+    <TextView
+        android:id="@+id/page_range_msg"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/all_pages"
+        android:textColor="@color/black"
+        app:layout_constraintTop_toTopOf="@id/page_range_text"
+        app:layout_constraintBottom_toBottomOf="@id/page_range_text"
+        app:layout_constraintEnd_toStartOf="@id/page_range_button" />
+
     <ImageButton
+        android:padding="10dp"
         android:id="@+id/page_range_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:src="?attr/actionModeCopyDrawable"
+        android:background="#00000000"
+        android:src="@drawable/ic_baseline_expand_more_24"
         app:layout_constraintBottom_toBottomOf="@id/page_range_text"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintTop_toTopOf="@id/page_range_text"/>

+ 134 - 0
app/src/main/res/layout-v31/activity_main.xml

@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity">
+
+    <androidx.appcompat.widget.Toolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="?actionBarSize"
+        android:elevation="4dp"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:title="@string/add_watermark" />
+
+    <com.google.android.material.tabs.TabLayout
+        android:id="@+id/tab_layout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:tabTextAppearance="@style/TabLayoutTextStyle"
+        app:layout_constraintTop_toBottomOf="@+id/toolbar"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <com.google.android.material.tabs.TabItem
+            android:id="@+id/text_item"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/text"
+            tools:layout_editor_absoluteX="164dp"
+            tools:layout_editor_absoluteY="52dp" />
+
+        <com.google.android.material.tabs.TabItem
+            android:id="@+id/image_item"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/image"
+            tools:layout_editor_absoluteX="164dp"
+            tools:layout_editor_absoluteY="52dp" />
+
+    </com.google.android.material.tabs.TabLayout>
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/page_image"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        android:contentDescription="@string/page_image" />
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/full_screen_mask"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        android:contentDescription="@string/full_screen_mask" />
+
+    <com.compdfkit.pdfviewer.customview.watermarkview.TextWatermarkView
+        android:id="@+id/watermark_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="@id/page_image"
+        app:layout_constraintBottom_toBottomOf="@id/page_image"
+        app:layout_constraintEnd_toEndOf="@id/page_image"
+        app:layout_constraintStart_toStartOf="@id/page_image"
+        app:image_mode="false" />
+
+    <com.compdfkit.pdfviewer.customview.watermarkview.ImageWatermarkView
+        android:id="@+id/watermark_image"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible"
+        app:layout_constraintTop_toTopOf="@id/page_image"
+        app:layout_constraintBottom_toBottomOf="@id/page_image"
+        app:layout_constraintEnd_toEndOf="@id/page_image"
+        app:layout_constraintStart_toStartOf="@id/page_image"
+        app:image_mode="false" />
+
+    <androidx.appcompat.widget.AppCompatImageButton
+        android:layout_margin="10dp"
+        android:id="@+id/expand_list_btn"
+        android:backgroundTint="@color/white"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible"
+        android:elevation="4dp"
+        app:srcCompat="@drawable/ic_baseline_keyboard_arrow_right_24"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintStart_toStartOf="parent"/>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/watermark_list"
+        android:layout_width="160dp"
+        android:layout_height="0dp"
+        android:background="@color/gray"
+        android:elevation="4dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintStart_toStartOf="parent"/>
+
+    <View
+        android:id="@+id/divider"
+        android:layout_width="409dp"
+        android:layout_height="1dp"
+        android:background="?android:attr/listDivider"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"/>
+
+    <androidx.fragment.app.FragmentContainerView
+        android:name="com.compdfkit.pdfviewer.fragments.WatermarkConsoleFragment"
+        android:id="@+id/console_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:tag="console_fragment"
+        android:elevation="4dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        tools:layout="@layout/fragment_watermark_console" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 347 - 0
app/src/main/res/layout-v31/fragment_watermark_console.xml

@@ -0,0 +1,347 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="10dp"
+    android:elevation="4dp"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    tools:context=".fragments.WatermarkConsoleFragment">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/picker"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@+id/opacity_icon"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" >
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/color_picker"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="8dp"
+            android:visibility="visible"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" >
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_selected"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/circle"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_1"
+                app:layout_constraintStart_toStartOf="parent" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_1"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle1_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_2"
+                app:layout_constraintStart_toEndOf="@id/color_selected" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_2"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle2_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_3"
+                app:layout_constraintStart_toEndOf="@id/color_1" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_3"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle3_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_4"
+                app:layout_constraintStart_toEndOf="@id/color_2" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_4"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle4_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_5"
+                app:layout_constraintStart_toEndOf="@id/color_3" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_5"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle5_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_6"
+                app:layout_constraintStart_toEndOf="@id/color_4" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_6"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle6_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toStartOf="@id/color_7"
+                app:layout_constraintStart_toEndOf="@id/color_5" />
+
+            <androidx.appcompat.widget.AppCompatImageView
+                android:id="@+id/color_7"
+                android:layout_width="35dp"
+                android:layout_height="35dp"
+                android:contentDescription="@string/opacity_icon"
+                android:src="@drawable/ic_baseline_circle7_24"
+                app:layout_constraintHorizontal_chainStyle="spread_inside"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toEndOf="@id/color_6" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:id="@+id/image_picker"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="5dp"
+            android:visibility="invisible"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" >
+
+            <TextView
+                android:id="@+id/image_select_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/image"
+                android:textSize="20sp"
+                android:padding="7dp"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent" />
+
+            <TextView
+                android:id="@+id/image_select_path"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:padding="3dp"
+                android:text="@string/default_image"
+                app:layout_constraintTop_toTopOf="@id/image_select_text"
+                app:layout_constraintBottom_toBottomOf="@id/image_select_text"
+                app:layout_constraintStart_toEndOf="@id/image_select_text"
+                app:layout_constraintEnd_toStartOf="@id/image_select_btn" />
+
+            <Button
+                android:id="@+id/image_select_btn"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/select_image"
+                app:layout_constraintTop_toTopOf="@+id/image_select_text"
+                app:layout_constraintBottom_toBottomOf="@id/image_select_text"
+                app:layout_constraintEnd_toEndOf="parent"
+                tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <ImageView
+        android:id="@+id/opacity_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:contentDescription="@string/opacity_icon"
+        android:src="@drawable/ic_baseline_opacity_20"
+        android:padding="10dp"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintEnd_toStartOf="@+id/opacity_slider"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/picker"
+        app:layout_constraintBottom_toTopOf="@+id/size_icon"/>
+
+    <androidx.appcompat.widget.AppCompatSeekBar
+        android:id="@+id/opacity_slider"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:progress="50"
+        android:theme="@style/SeekBarColor"
+        app:layout_constraintTop_toTopOf="@id/opacity_icon"
+        app:layout_constraintBottom_toBottomOf="@id/opacity_icon"
+        app:layout_constraintStart_toEndOf="@+id/opacity_icon"
+        app:layout_constraintEnd_toStartOf="@id/opacity_text"/>
+
+    <TextView
+        android:id="@+id/opacity_text"
+        android:layout_width="40dp"
+        android:layout_height="wrap_content"
+        android:text="@string/default_opacity"
+        app:layout_constraintTop_toTopOf="@id/opacity_icon"
+        app:layout_constraintBottom_toBottomOf="@id/opacity_icon"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/opacity_slider" />
+
+
+    <ImageView
+        android:id="@+id/size_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:contentDescription="@string/opacity_icon"
+        android:src="@drawable/ic_baseline_format_size_20"
+        android:padding="10dp"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintEnd_toStartOf="@+id/size_slider"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/opacity_icon"
+        app:layout_constraintBottom_toTopOf="@+id/page_range_text"/>
+
+    <androidx.appcompat.widget.AppCompatSeekBar
+        android:id="@+id/size_slider"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:progress="50"
+        android:theme="@style/SeekBarColor"
+        app:layout_constraintTop_toTopOf="@id/size_icon"
+        app:layout_constraintBottom_toBottomOf="@id/size_icon"
+        app:layout_constraintStart_toEndOf="@+id/size_icon"
+        app:layout_constraintEnd_toStartOf="@id/size_text"/>
+
+    <TextView
+        android:id="@+id/size_text"
+        android:layout_width="40dp"
+        android:layout_height="wrap_content"
+        android:text="@string/default_scale"
+        app:layout_constraintTop_toTopOf="@id/size_icon"
+        app:layout_constraintBottom_toBottomOf="@id/size_icon"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/size_slider" />
+
+
+    <TextView
+        android:id="@+id/page_range_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/page_range"
+        android:textSize="20sp"
+        android:padding="12dp"
+        app:layout_constraintTop_toBottomOf="@+id/size_icon"
+        app:layout_constraintBottom_toTopOf="@id/full_screen_checkbox"
+        app:layout_constraintStart_toStartOf="parent" />
+
+    <TextView
+        android:id="@+id/page_range_msg"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/all_pages"
+        app:layout_constraintTop_toTopOf="@id/page_range_text"
+        app:layout_constraintBottom_toBottomOf="@id/page_range_text"
+        app:layout_constraintEnd_toStartOf="@id/page_range_button" />
+
+    <ImageButton
+        android:padding="10dp"
+        android:id="@+id/page_range_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="#00000000"
+        android:src="@drawable/ic_baseline_expand_more_24"
+        app:layout_constraintBottom_toBottomOf="@id/page_range_text"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@id/page_range_text"/>
+
+
+    <CheckBox
+        android:id="@+id/full_screen_checkbox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="10dp"
+        android:text="@string/full_screen"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/page_range_text"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/full_screen_space"
+        tools:ignore="TouchTargetSizeCheck" />
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/full_screen_space"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="@id/full_screen_checkbox"
+        app:layout_constraintBottom_toBottomOf="@id/full_screen_checkbox"
+        app:layout_constraintStart_toEndOf="@id/full_screen_checkbox"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:id="@+id/horizontal_space"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:hint="@string/default_space"
+            android:text="@string/default_space"
+            android:enabled="false"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/horizontal_space_mm"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:ignore="TouchTargetSizeCheck,DuplicateSpeakableTextCheck" />
+
+        <TextView
+            android:id="@+id/horizontal_space_mm"
+            android:layout_width="40dp"
+            android:layout_height="wrap_content"
+            android:text="@string/mm"
+            app:layout_constraintTop_toTopOf="@id/horizontal_space"
+            app:layout_constraintBottom_toBottomOf="@id/horizontal_space"
+            app:layout_constraintStart_toEndOf="@+id/horizontal_space"
+            app:layout_constraintEnd_toStartOf="@id/vertical_space"/>
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:id="@+id/vertical_space"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:hint="@string/default_space"
+            android:text="@string/default_space"
+            android:enabled="false"
+            app:layout_constraintBottom_toBottomOf="@id/horizontal_space"
+            app:layout_constraintEnd_toStartOf="@id/vertical_space_mm"
+            app:layout_constraintStart_toEndOf="@id/horizontal_space_mm"
+            app:layout_constraintTop_toTopOf="@id/horizontal_space"
+            tools:ignore="TouchTargetSizeCheck" />
+
+        <TextView
+            android:id="@+id/vertical_space_mm"
+            android:layout_width="40dp"
+            android:layout_height="wrap_content"
+            android:text="@string/mm"
+            app:layout_constraintTop_toTopOf="@id/horizontal_space"
+            app:layout_constraintBottom_toBottomOf="@id/horizontal_space"
+            app:layout_constraintStart_toEndOf="@+id/vertical_space"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 46 - 10
app/src/main/res/layout/activity_main.xml

@@ -16,8 +16,8 @@
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:title="Add Watermark"
-        app:titleTextColor="@color/white" />
+        app:title="@string/add_watermark"
+        app:titleTextColor="?attr/colorOnPrimary" />
 
     <com.google.android.material.tabs.TabLayout
         android:id="@+id/tab_layout"
@@ -26,9 +26,9 @@
         android:elevation="4dp"
         android:background="?attr/colorPrimary"
         app:tabTextAppearance="@style/TabLayoutTextStyle"
-        app:tabIndicatorColor="@color/white"
-        app:tabSelectedTextColor="@color/white"
-        app:tabTextColor="@color/purple_200"
+        app:tabIndicatorColor="?attr/colorOnPrimary"
+        app:tabSelectedTextColor="?attr/colorOnPrimary"
+        app:tabTextColor="?attr/colorSecondary"
         app:layout_constraintTop_toBottomOf="@+id/toolbar"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent">
@@ -51,7 +51,7 @@
 
     </com.google.android.material.tabs.TabLayout>
 
-    <ImageView
+    <androidx.appcompat.widget.AppCompatImageView
         android:id="@+id/page_image"
         android:layout_width="wrap_content"
         android:layout_height="0dp"
@@ -61,7 +61,18 @@
         app:layout_constraintStart_toStartOf="parent"
         android:contentDescription="@string/page_image" />
 
-    <com.compdfkit.pdfviewer.customview.TextWatermarkView
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/full_screen_mask"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        android:contentDescription="@string/full_screen_mask" />
+
+    <com.compdfkit.pdfviewer.customview.watermarkview.TextWatermarkView
         android:id="@+id/watermark_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -71,7 +82,7 @@
         app:layout_constraintStart_toStartOf="@id/page_image"
         app:image_mode="false" />
 
-    <com.compdfkit.pdfviewer.customview.ImageWatermarkView
+    <com.compdfkit.pdfviewer.customview.watermarkview.ImageWatermarkView
         android:id="@+id/watermark_image"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -82,15 +93,40 @@
         app:layout_constraintStart_toStartOf="@id/page_image"
         app:image_mode="false" />
 
+    <androidx.appcompat.widget.AppCompatImageButton
+        android:layout_margin="10dp"
+        android:id="@+id/expand_list_btn"
+        android:backgroundTint="@color/white"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="invisible"
+        android:elevation="4dp"
+        app:srcCompat="@drawable/ic_baseline_keyboard_arrow_right_24"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintStart_toStartOf="parent"/>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/watermark_list"
+        android:layout_width="160dp"
+        android:layout_height="0dp"
+        android:background="@color/gray"
+        android:elevation="4dp"
+        android:visibility="invisible"
+        app:layout_constraintTop_toBottomOf="@id/tab_layout"
+        app:layout_constraintBottom_toTopOf="@id/console_view"
+        app:layout_constraintStart_toStartOf="parent"/>
+
     <androidx.fragment.app.FragmentContainerView
         android:name="com.compdfkit.pdfviewer.fragments.WatermarkConsoleFragment"
         android:id="@+id/console_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:elevation="4dp"
         android:tag="console_fragment"
+        android:elevation="4dp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent" />
+        app:layout_constraintEnd_toEndOf="parent"
+        tools:layout="@layout/fragment_watermark_console" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 13 - 12
app/src/main/res/layout/fragment_watermark_console.xml

@@ -3,8 +3,9 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@color/white"
+    android:background="?attr/colorOnPrimary"
     android:padding="10dp"
+    android:elevation="4dp"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     tools:context=".fragments.WatermarkConsoleFragment">
 
@@ -28,7 +29,7 @@
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintEnd_toEndOf="parent" >
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_selected"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
@@ -40,7 +41,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_1"
                 app:layout_constraintStart_toStartOf="parent" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_1"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -52,7 +53,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_2"
                 app:layout_constraintStart_toEndOf="@id/color_selected" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_2"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -64,7 +65,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_3"
                 app:layout_constraintStart_toEndOf="@id/color_1" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_3"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -76,7 +77,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_4"
                 app:layout_constraintStart_toEndOf="@id/color_2" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_4"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -88,7 +89,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_5"
                 app:layout_constraintStart_toEndOf="@id/color_3" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_5"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -100,7 +101,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_6"
                 app:layout_constraintStart_toEndOf="@id/color_4" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_6"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -112,7 +113,7 @@
                 app:layout_constraintEnd_toStartOf="@id/color_7"
                 app:layout_constraintStart_toEndOf="@id/color_5" />
 
-            <ImageView
+            <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/color_7"
                 android:layout_width="35dp"
                 android:layout_height="35dp"
@@ -164,9 +165,9 @@
                 android:id="@+id/image_select_btn"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="Select"
+                android:text="@string/select_image"
                 android:textColor="@color/white"
-                android:backgroundTint="@color/purple_500"
+                android:backgroundTint="?attr/colorPrimary"
                 app:layout_constraintTop_toTopOf="@+id/image_select_text"
                 app:layout_constraintBottom_toBottomOf="@id/image_select_text"
                 app:layout_constraintEnd_toEndOf="parent"
@@ -272,7 +273,7 @@
         android:id="@+id/page_range_button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:background="@color/white"
+        android:background="#00000000"
         android:src="@drawable/ic_baseline_expand_more_24"
         app:layout_constraintBottom_toBottomOf="@id/page_range_text"
         app:layout_constraintEnd_toEndOf="parent"

+ 2 - 2
app/src/main/res/layout/range_selector.xml

@@ -16,14 +16,14 @@
             android:id="@+id/all_pages"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="All pages"
+            android:text="@string/all_pages"
             android:checked="true"/>
 
         <androidx.appcompat.widget.AppCompatRadioButton
             android:id="@+id/custom_range"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="Custom range" />
+            android:text="@string/custom_range" />
 
     </RadioGroup>
 

+ 1 - 1
app/src/main/res/layout/watermark_image_view.xml

@@ -14,7 +14,7 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" >
 
-        <ImageView
+        <androidx.appcompat.widget.AppCompatImageView
             android:id="@+id/image_watermark"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"

+ 41 - 0
app/src/main/res/layout/watermark_item.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:padding="6dp"
+    android:background="@color/white"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/watermark_type_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="10dp"
+        android:src="@drawable/ic_baseline_text_type_24"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/watermark_content"/>
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/watermark_content"
+        android:layout_width="80dp"
+        android:layout_height="wrap_content"
+        android:maxEms="5"
+        android:ellipsize="end"
+        android:text="test"
+        app:layout_constraintTop_toTopOf="@id/watermark_type_icon"
+        app:layout_constraintBottom_toBottomOf="@id/watermark_type_icon"
+        app:layout_constraintStart_toEndOf="@id/watermark_type_icon"
+        app:layout_constraintEnd_toStartOf="@id/hint_icon"/>
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/hint_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_baseline_keyboard_arrow_right_24"
+        app:layout_constraintTop_toTopOf="@id/watermark_type_icon"
+        app:layout_constraintBottom_toBottomOf="@id/watermark_type_icon"
+        app:layout_constraintStart_toEndOf="@id/watermark_content" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 36 - 0
app/src/main/res/layout/watermark_item_layout.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:background="@color/white">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/delete_view"
+        android:layout_width="80dp"
+        android:layout_height="0dp"
+        android:background="#e06666"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent">
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:srcCompat="@drawable/ic_baseline_delete_forever_24"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <com.compdfkit.pdfviewer.customview.WatermarkListItem
+        android:id="@+id/item_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
app/src/main/res/layout/watermark_text_view.xml

@@ -25,7 +25,7 @@
             android:textSize="35sp"
             android:visibility="visible"
             android:alpha="0.5"
-            android:letterSpacing="0.012"
+            android:maxLines="1"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"

+ 0 - 105
app/src/main/res/layout/watermark_view.xml

@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/watermark_t"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" >
-
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/watermark_t_container"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:background="@drawable/watermark_shape"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent" >
-            <TextView
-                android:id="@+id/text_watermark"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:padding="15dp"
-                android:text="@string/watermark"
-                android:textColor="#FF0000"
-                android:textSize="35sp"
-                android:visibility="visible"
-                android:alpha="0.5"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent" />
-        </androidx.constraintlayout.widget.ConstraintLayout>
-
-        <ImageButton
-            android:id="@+id/watermark_t_handle"
-            android:layout_width="20dp"
-            android:layout_height="20dp"
-            android:background="@drawable/watermark_handle_shape"
-            android:contentDescription="@string/watermark_handle"
-            app:layout_constraintBottom_toBottomOf="@+id/watermark_t_container"
-            app:layout_constraintEnd_toEndOf="@+id/watermark_t_container"
-            app:layout_constraintStart_toEndOf="@+id/watermark_t_container"
-            app:layout_constraintTop_toBottomOf="@+id/watermark_t_container"
-            app:srcCompat="@drawable/ic_white_roll_15"
-            tools:ignore="TouchTargetSizeCheck" />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/watermark_i"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        android:visibility="invisible">
-
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/watermark_i_container"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:background="@drawable/watermark_shape"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent" >
-            <ImageView
-                android:id="@+id/image_watermark"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:padding="15dp"
-                android:src="@drawable/pdf"
-                android:alpha="0.5"
-                android:visibility="visible"
-                app:layout_constraintTop_toTopOf="parent"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintEnd_toEndOf="parent"
-                android:contentDescription="@string/watermark_image" />
-        </androidx.constraintlayout.widget.ConstraintLayout>
-
-        <ImageButton
-            android:id="@+id/watermark_i_handle"
-            android:layout_width="20dp"
-            android:layout_height="20dp"
-            app:srcCompat="@drawable/ic_white_roll_15"
-            android:background="@drawable/watermark_handle_shape"
-            app:layout_constraintTop_toBottomOf="@+id/watermark_i_container"
-            app:layout_constraintBottom_toBottomOf="@+id/watermark_i_container"
-            app:layout_constraintStart_toEndOf="@+id/watermark_i_container"
-            app:layout_constraintEnd_toEndOf="@+id/watermark_i_container"
-            android:contentDescription="@string/watermark_handle" />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>

+ 7 - 0
app/src/main/res/menu/menu_done.xml

@@ -2,6 +2,13 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
+    <item
+        android:id="@+id/edit"
+        android:icon="@drawable/ic_baseline_edit_note_24"
+        android:title="@string/edit_watermark"
+        android:onClick="changeEditMode"
+        app:showAsAction="always"/>
+
     <item
         android:id="@+id/done"
         android:icon="@drawable/ic_baseline_done_24"

+ 18 - 0
app/src/main/res/values-night-v31/themes.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+<!-- Base application theme. -->
+    <style name="Theme.PDFViewer" parent="Theme.Material3.DayNight.NoActionBar">
+        <!-- Primary brand color. -->
+        <item name="colorPrimary">@color/purple_200</item>
+        <item name="colorPrimaryVariant">@color/purple_700</item>
+        <item name="colorOnPrimary">@color/black</item>
+        <!-- Secondary brand color. -->
+        <item name="colorSecondary">@color/teal_200</item>
+        <item name="colorSecondaryVariant">@color/teal_200</item>
+        <item name="colorOnSecondary">@color/black</item>
+        <!-- Status bar color. -->
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
+        <!-- Customize your theme here. -->
+    </style>
+</resources>

+ 2 - 1
app/src/main/res/values-night/themes.xml

@@ -1,6 +1,6 @@
 <resources xmlns:tools="http://schemas.android.com/tools">
     <!-- Base application theme. -->
-    <style name="Theme.PDFViewer" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
+    <style name="Theme.PDFViewer" parent="Theme.MaterialComponents.DayNight.NoActionBar">
         <!-- Primary brand color. -->
         <item name="colorPrimary">@color/purple_200</item>
         <item name="colorPrimaryVariant">@color/purple_700</item>
@@ -11,6 +11,7 @@
         <item name="colorOnSecondary">@color/black</item>
         <!-- Status bar color. -->
         <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
         <!-- Customize your theme here. -->
     </style>
 </resources>

+ 19 - 0
app/src/main/res/values-notnight-v31/themes.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools">
+    <!-- Base application theme. -->
+    <style name="Theme.PDFViewer" parent="Theme.Material3.Light.NoActionBar">
+        <!-- Primary brand color. -->
+        <item name="colorPrimary">@color/purple_500</item>
+        <item name="colorPrimaryVariant">@color/purple_700</item>
+        <item name="colorOnPrimary">@color/white</item>
+        
+        <!-- Secondary brand color. -->
+        <item name="colorSecondary">@color/purple_200</item>
+        <item name="colorSecondaryVariant">@color/teal_700</item>
+        <item name="colorOnSecondary">@color/black</item>
+        <!-- Status bar color. -->
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
+        <!-- Customize your theme here. -->
+    </style>
+</resources>

+ 30 - 0
app/src/main/res/values-zh/strings.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">PDFViewer</string>
+    <string name="add_watermark">添加水印</string>
+    <string name="edit_watermark">编辑水印</string>
+    <string name="text">文本</string>
+    <string name="image">图片</string>
+    <string name="opacity_icon">Opacity icon</string>
+    <string name="full_screen">平铺</string>
+    <string name="default_opacity">50%</string>
+    <string name="default_scale">100%</string>
+    <string name="page_range">页面范围</string>
+    <string name="mm">mm</string>
+    <string name="default_space">100</string>
+    <string name="watermark_image">水印图像</string>
+    <string name="text_watermark">文字水印</string>
+    <string name="watermark">Watermark</string>
+    <string name="watermark_handle">水印旋转</string>
+    <string name="default_image">默认图像</string>
+    <string name="select_image">选择图像</string>
+    <string name="done">完成</string>
+    <string name="page_image">页面图像</string>
+    <string name="range_hint">例如: 1,3–5,10</string>
+    <string name="watermark_context">水印内容</string>
+    <string name="all_pages">全部页面</string>
+    <string name="setting_range">设置页面范围</string>
+    <string name="custom_range">自定义页面范围</string>
+    <string name="cancel">取消</string>
+    <string name="full_screen_mask">Full screen mask</string>
+</resources>

+ 1 - 0
app/src/main/res/values/colors.xml

@@ -7,4 +7,5 @@
     <color name="teal_700">#FF018786</color>
     <color name="black">#FF000000</color>
     <color name="white">#FFFFFFFF</color>
+    <color name="gray">#FFF8F8F8</color>
 </resources>

+ 9 - 3
app/src/main/res/values/strings.xml

@@ -1,9 +1,9 @@
 <resources>
     <string name="app_name">PDFViewer</string>
+    <string name="add_watermark">Add watermark</string>
+    <string name="edit_watermark">Edit watermark</string>
     <string name="text">Text</string>
     <string name="image">Image</string>
-    <!-- TODO: Remove or change this placeholder text -->
-    <string name="hello_blank_fragment">Hello blank fragment</string>
     <string name="opacity_icon">Opacity icon</string>
     <string name="full_screen">Full screen</string>
     <string name="default_opacity">50%</string>
@@ -12,12 +12,18 @@
     <string name="mm">mm</string>
     <string name="default_space">100</string>
     <string name="watermark_image">watermark image</string>
+    <string name="text_watermark">Text watermark</string>
     <string name="watermark">Watermark</string>
     <string name="watermark_handle">Watermark Handle</string>
     <string name="default_image">Default image</string>
+    <string name="select_image">select</string>
     <string name="done">Done</string>
     <string name="page_image">Page Image</string>
-    <string name="range_hint">Such as: 1,3-5,10</string>
+    <string name="range_hint">Such as: 1,35,10</string>
     <string name="watermark_context">Watermark context</string>
     <string name="all_pages">All pages</string>
+    <string name="setting_range">Setting range</string>
+    <string name="custom_range">Custom range</string>
+    <string name="cancel">Cancel</string>
+    <string name="full_screen_mask">Full screen mask</string>
 </resources>

+ 1 - 1
app/src/main/res/values/styles.xml

@@ -6,6 +6,6 @@
     </style>
     <style name="SeekBarColor"
         parent="Widget.AppCompat.SeekBar">
-        <item name="colorAccent">@color/purple_500</item>
+        <item name="colorAccent">?attr/colorPrimary</item>
     </style>
 </resources>

+ 5 - 3
app/src/main/res/values/themes.xml

@@ -1,17 +1,19 @@
 <resources xmlns:tools="http://schemas.android.com/tools">
     <!-- Base application theme. -->
-    <style name="Theme.PDFViewer" parent="Theme.AppCompat.Light.NoActionBar">
+    <style name="Theme.PDFViewer" parent="Theme.MaterialComponents.Light.NoActionBar">
         <!-- Primary brand color. -->
         <item name="colorPrimary">@color/purple_500</item>
         <item name="colorPrimaryVariant">@color/purple_700</item>
         <item name="colorOnPrimary">@color/white</item>
+
+
         <!-- Secondary brand color. -->
-        <item name="colorSecondary">@color/teal_200</item>
+        <item name="colorSecondary">@color/purple_200</item>
         <item name="colorSecondaryVariant">@color/teal_700</item>
         <item name="colorOnSecondary">@color/black</item>
         <!-- Status bar color. -->
         <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
         <!-- Customize your theme here. -->
     </style>
-
 </resources>