Merge branch 'organicmaps:master' into master
|
@ -4,7 +4,7 @@
|
|||
BasedOnStyle: Google
|
||||
IndentWidth: 2
|
||||
BreakBeforeBraces: Allman
|
||||
ColumnLimit: 100
|
||||
ColumnLimit: 120
|
||||
|
||||
---
|
||||
Language: Cpp
|
||||
|
@ -21,7 +21,7 @@ IndentCaseLabels: false
|
|||
NamespaceIndentation: None
|
||||
PointerAlignment: Middle
|
||||
SortIncludes: true
|
||||
Standard: Cpp11
|
||||
Standard: c++17
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
# Tests --------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
6aa73face8b5eb8e026cfafa40d1983d4a0502c0
|
||||
480fa6c2fcf53be296504ac6ba8e6b3d70f92b42
|
||||
a6ede2b1466f0c9d8a443600ef337ba6b5832e58
|
||||
|
|
9
.github/CODEOWNERS
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Require legal approval for all new graphics
|
||||
android/app/src/main/res/drawable*/ @organicmaps/legal
|
||||
android/app/src/main/res/fonts/ @organicmaps/legal
|
||||
android/app/src/main/res/mipmap*/ @organicmaps/legal
|
||||
data/*.ttf @organicmaps/legal
|
||||
data/resources*/ @organicmaps/legal
|
||||
data/search-icons/ @organicmaps/legal
|
||||
data/styles/clear/style-*/ @organicmaps/legal
|
||||
iphone/Maps/Images.xcassets/ @organicmaps/legal
|
19
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,14 +1,17 @@
|
|||
---
|
||||
name: Bug Report
|
||||
about: Describe your issue in details to help us improve Organic Maps
|
||||
about: Describe your issue in detail to help us improve Organic Maps
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
⚠ Have you searched for similar, already existing issues?
|
||||
|
||||
**Describe the issue**
|
||||
Please write here a clear and concise description of what the bug/issue is about.
|
||||
Please write a clear and concise description of the issue here.
|
||||
|
||||
|
||||
**Steps to reproduce**
|
||||
1. Go to '...'
|
||||
|
@ -16,16 +19,20 @@ Please write here a clear and concise description of what the bug/issue is about
|
|||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
**Expected behaviour**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots or screen recordings to help explain your problem.
|
||||
|
||||
|
||||
**System information:**
|
||||
- Operating system and its version: [iOS 12, Android 10, Ubuntu 22, MacOS Big Sur, etc.]
|
||||
- Organic Maps version: [you can find it by clicking the "?" button]
|
||||
- Device Model: [e.g. iPhone6, Samsung S22]
|
||||
- Organic Maps version: [you can find it by tapping the button with the green Organic Maps logo]
|
||||
- Device Model: [e.g. iPhone 6, Samsung S22]
|
||||
|
||||
|
||||
**Additional context**
|
||||
Please add any other context and important details/notes/comments about the problem here.
|
||||
Please add any other context or comments here that may be useful.
|
||||
|
|
4
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -2,10 +2,10 @@ blank_issues_enabled: true
|
|||
contact_links:
|
||||
- name: Discussions
|
||||
url: https://github.com/organicmaps/organicmaps/discussions
|
||||
about: Discuss the usage of OrganicMaps, ask questions, or talk about ideas that are not yet actionable.
|
||||
about: Discuss the usage of Organic Maps, ask questions, or talk about ideas that aren't yet actionable.
|
||||
- name: Translations
|
||||
url: https://github.com/organicmaps/organicmaps/blob/master/docs/TRANSLATIONS.md
|
||||
about: Translate Organic Maps into your language
|
||||
- name: News
|
||||
url: https://organicmaps.app/news/
|
||||
about: Check the latest project news
|
||||
about: Check the latest project news
|
||||
|
|
11
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -1,22 +1,27 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for OrganicMaps
|
||||
name: Feature Request
|
||||
about: Suggest an idea for Organic Maps
|
||||
title: ''
|
||||
labels: [Enhancement]
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
⚠ Have you searched for similar, already existing issues?
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. For example:
|
||||
I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you would like**
|
||||
|
||||
**Describe the ideal solution**
|
||||
A clear and concise description of what you want to see in Organic Maps.
|
||||
|
||||
|
||||
**Describe alternatives you have considered**
|
||||
- How do you solve this issue now with Organic Maps or other apps?
|
||||
- Attach any examples, screenshots, or screen recordings from other apps that help us to better understand the idea.
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
|
15
.github/workflows/android-beta.yaml
vendored
|
@ -19,6 +19,12 @@ on:
|
|||
- docs/**
|
||||
- generator/**
|
||||
- packaging/**
|
||||
- platform/*apple*
|
||||
- platform/*_ios*
|
||||
- platform/*_linux*
|
||||
- platform/*_mac*
|
||||
- platform/*qt*
|
||||
- platform/*_win*
|
||||
- pyhelpers/**
|
||||
- qt*/**
|
||||
- skin_generator/**
|
||||
|
@ -26,6 +32,9 @@ on:
|
|||
- track_generator/**
|
||||
- xcode/**
|
||||
|
||||
env:
|
||||
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
|
||||
|
||||
jobs:
|
||||
android-google-beta:
|
||||
name: Android Google Beta
|
||||
|
@ -39,7 +48,7 @@ jobs:
|
|||
sudo apt-get install -y ninja-build
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100 # enough to get all commits for the current day
|
||||
|
||||
|
@ -48,7 +57,7 @@ jobs:
|
|||
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
|
||||
|
||||
- name: Checkout private keys
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.PRIVATE_REPO }}
|
||||
ssh-key: ${{ secrets.PRIVATE_SSH_KEY }}
|
||||
|
@ -67,7 +76,7 @@ jobs:
|
|||
run: |
|
||||
cmake --version
|
||||
ninja --version
|
||||
gradle -x lint -x lintVitalGoogleBeta assembleGoogleBeta uploadCrashlyticsSymbolFileGoogleBeta uploadCrashlyticsMappingFileGoogleBeta
|
||||
./gradlew -Pfirebase -x lint -x lintVitalGoogleBeta assembleGoogleBeta uploadCrashlyticsSymbolFileGoogleBeta uploadCrashlyticsMappingFileGoogleBeta
|
||||
|
||||
- name: Upload beta apk to App Distribution
|
||||
shell: bash
|
||||
|
|
|
@ -4,8 +4,8 @@ on:
|
|||
pull_request:
|
||||
paths:
|
||||
- .github/workflows/android-check-metadata.yaml # Run check on self change
|
||||
- android/src/fdroid/**
|
||||
- android/src/google/**
|
||||
- android/app/src/fdroid/**
|
||||
- android/app/src/google/**
|
||||
- tools/python/check_store_metadata.py
|
||||
|
||||
jobs:
|
||||
|
@ -14,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check metadata
|
||||
run: ./tools/python/check_store_metadata.py android
|
||||
|
|
40
.github/workflows/android-check.yaml
vendored
|
@ -1,6 +1,9 @@
|
|||
name: Android Check
|
||||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- .gitignore
|
||||
|
@ -11,13 +14,19 @@ on:
|
|||
- LICENSE
|
||||
- NOTICE
|
||||
- README.md
|
||||
- android/src/fdroid/**
|
||||
- android/src/google/**
|
||||
- android/app/src/fdroid/**
|
||||
- android/app/src/google/**
|
||||
- iphone/**
|
||||
- data/strings/**
|
||||
- docs/**
|
||||
- generator/**
|
||||
- packaging/**
|
||||
- platform/*apple*
|
||||
- platform/*_ios*
|
||||
- platform/*_linux*
|
||||
- platform/*_mac*
|
||||
- platform/*qt*
|
||||
- platform/*_win*
|
||||
- pyhelpers/**
|
||||
- qt*/**
|
||||
- skin_generator/**
|
||||
|
@ -25,13 +34,16 @@ on:
|
|||
- track_generator/**
|
||||
- xcode/**
|
||||
|
||||
env:
|
||||
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Android Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
@ -46,7 +58,7 @@ jobs:
|
|||
- name: Lint
|
||||
shell: bash
|
||||
working-directory: android
|
||||
run: gradle lint
|
||||
run: ./gradlew -Pandroidauto=true lint
|
||||
|
||||
android-check:
|
||||
name: Build Android Debug
|
||||
|
@ -55,6 +67,10 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
flavor: [WebDebug, FdroidBeta]
|
||||
# Cancels previous jobs if the same branch or PR was updated again.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ matrix.flavor }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Install build tools and dependencies
|
||||
|
@ -64,7 +80,7 @@ jobs:
|
|||
sudo apt-get install -y ninja-build
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 200 # enough to get all commits for the current day
|
||||
|
||||
|
@ -76,17 +92,25 @@ jobs:
|
|||
shell: bash
|
||||
run: ./configure.sh
|
||||
|
||||
- name: Configure ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ matrix.flavor }}
|
||||
|
||||
- name: Compile ${{ matrix.flavor }}
|
||||
shell: bash
|
||||
working-directory: android
|
||||
env:
|
||||
CMAKE_C_COMPILER_LAUNCHER: ccache
|
||||
CMAKE_CXX_COMPILER_LAUNCHER: ccache
|
||||
run: |
|
||||
cmake --version
|
||||
ninja --version
|
||||
gradle -Parm64 assemble${{ matrix.flavor }}
|
||||
./gradlew -Parm64 assemble${{ matrix.flavor }}
|
||||
|
||||
- name: Upload arm64-v8a ${{ matrix.flavor }} apk
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: android-arm64-v8a-${{ matrix.flavor }}
|
||||
path: android/build/outputs/apk/**/OrganicMaps-*.apk
|
||||
path: android/app/build/outputs/apk/**/OrganicMaps-*.apk
|
||||
if-no-files-found: error
|
||||
|
|
24
.github/workflows/android-monkey.yaml
vendored
|
@ -2,7 +2,10 @@ name: Android Monkey
|
|||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
schedule:
|
||||
- cron: '0 5 * * *' # Once per day at 05:00 UTC
|
||||
- cron: '0 5 * * 0' # Once per week at 05:00 UTC
|
||||
|
||||
env:
|
||||
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
|
||||
|
||||
jobs:
|
||||
precondition:
|
||||
|
@ -10,7 +13,7 @@ jobs:
|
|||
name: Check preconditions
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1000 # fetch month or so
|
||||
|
||||
|
@ -45,7 +48,7 @@ jobs:
|
|||
uses: google-github-actions/setup-gcloud@v0
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100 # enough to get all commits for the current day
|
||||
|
||||
|
@ -54,7 +57,7 @@ jobs:
|
|||
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
|
||||
|
||||
- name: Checkout private keys
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.PRIVATE_REPO }}
|
||||
ssh-key: ${{ secrets.PRIVATE_SSH_KEY }}
|
||||
|
@ -73,16 +76,17 @@ jobs:
|
|||
run: |
|
||||
cmake --version
|
||||
ninja --version
|
||||
gradle -Pfirebase assembleGoogleDebug uploadCrashlyticsSymbolFileGoogleDebug
|
||||
./gradlew -Pfirebase -Parm64-v8a -Parmeabi-v7a -Px86_64 assembleGoogleDebug uploadCrashlyticsSymbolFileGoogleDebug
|
||||
|
||||
- name: Run monkey
|
||||
run: |
|
||||
gcloud auth activate-service-account --key-file android/firebase-test-lab.json
|
||||
gcloud auth activate-service-account --key-file android/app/firebase-test-lab.json
|
||||
gcloud config set project omapsapp
|
||||
gcloud firebase test android run --app ./android/build/outputs/apk/google/debug/OrganicMaps-*-google-debug.apk \
|
||||
--device model=panther,version=33 \
|
||||
gcloud firebase test android run --app ./android/app/build/outputs/apk/google/debug/OrganicMaps-*-google-debug.apk \
|
||||
--device model=husky,version=34 \
|
||||
--device model=cheetah,version=33 \
|
||||
--device model=bluejay,version=32 \
|
||||
--device model=b2q,version=31 \
|
||||
--device model=a51,version=31 \
|
||||
--device model=f2q,version=30 \
|
||||
--device model=a10,version=29 \
|
||||
--device model=Pixel2.arm,version=30 \
|
||||
|
@ -93,6 +97,4 @@ jobs:
|
|||
--device model=Nexus6,version=25 \
|
||||
--device model=NexusLowRes,version=24 \
|
||||
--device model=NexusLowRes,version=23,orientation=landscape \
|
||||
--device model=Nexus6,version=22 \
|
||||
--device model=Nexus7,version=21 \
|
||||
--timeout 15m
|
||||
|
|
|
@ -2,6 +2,9 @@ name: Android Release Metadata
|
|||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
|
||||
env:
|
||||
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
|
||||
|
||||
jobs:
|
||||
android-release-metadata:
|
||||
name: Upload Google Play metadata
|
||||
|
@ -9,14 +12,14 @@ jobs:
|
|||
environment: production
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Parallel submodules checkout
|
||||
shell: bash
|
||||
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
|
||||
|
||||
- name: Checkout screenshots
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.SCREENSHOTS_REPO }}
|
||||
ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
|
||||
|
@ -24,7 +27,7 @@ jobs:
|
|||
path: screenshots
|
||||
|
||||
- name: Checkout private keys
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.PRIVATE_REPO }}
|
||||
ssh-key: ${{ secrets.PRIVATE_SSH_KEY }}
|
||||
|
|
37
.github/workflows/android-release.yaml
vendored
|
@ -3,8 +3,9 @@ on:
|
|||
workflow_dispatch: # Manual trigger
|
||||
|
||||
env:
|
||||
RELEASE_NOTES: android/src/google/play/release-notes/en-US/default.txt
|
||||
FDROID_VERSION: android/src/fdroid/play/version.yaml
|
||||
RELEASE_NOTES: android/app/src/google/play/release-notes/en-US/default.txt
|
||||
FDROID_VERSION: android/app/src/fdroid/play/version.yaml
|
||||
JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin
|
||||
|
||||
jobs:
|
||||
tag:
|
||||
|
@ -13,7 +14,7 @@ jobs:
|
|||
environment: production
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100 # Enough to get all commits for the last day.
|
||||
ssh-key: ${{ secrets.RELEASE_SSH_KEY }}
|
||||
|
@ -28,15 +29,17 @@ jobs:
|
|||
version=$(tools/unix/version.sh ios_version)
|
||||
# +1 because below a "Bump versions" commit is created.
|
||||
# TODO: Find a way to refactor FDroid versioning without that additional commit.
|
||||
build=$(($(tools/unix/version.sh ios_build) + 1))
|
||||
code=$(($(tools/unix/version.sh android_code) + 1))
|
||||
# build=$(($(tools/unix/version.sh ios_build) + 1))
|
||||
# code=$(($(tools/unix/version.sh android_code) + 1))
|
||||
build=$(tools/unix/version.sh ios_build)
|
||||
code=$(tools/unix/version.sh android_code)
|
||||
tag=$version-$build-android
|
||||
echo "::set-output name=version::$version"
|
||||
echo "::set-output name=build::$build"
|
||||
echo "::set-output name=tag::$tag"
|
||||
echo "::set-output name=code::$code"
|
||||
echo "version: ${version}-${build}-FDroid+${code}" > ${{ env.FDROID_VERSION }}
|
||||
git add ${{ env.FDROID_VERSION }}
|
||||
# echo "version: ${version}-${build}-FDroid+${code}" > ${{ env.FDROID_VERSION }}
|
||||
# git add ${{ env.FDROID_VERSION }}
|
||||
{
|
||||
echo $tag
|
||||
echo
|
||||
|
@ -44,7 +47,7 @@ jobs:
|
|||
} > ${{ runner.temp }}/tag.txt
|
||||
branch="${GITHUB_REF#refs/heads/}"
|
||||
test -n "$branch"
|
||||
git commit -m "Bump versions" -s
|
||||
# git commit -m "Bump versions" -s
|
||||
git tag -a $tag -F ${{ runner.temp }}/tag.txt
|
||||
git show $tag
|
||||
git push origin $branch:$branch
|
||||
|
@ -75,7 +78,7 @@ jobs:
|
|||
sudo apt-get install -y ninja-build
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100 # enough to get all commits for the current day
|
||||
ref: 'refs/tags/${{ needs.tag.outputs.tag }}'
|
||||
|
@ -92,7 +95,7 @@ jobs:
|
|||
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
|
||||
|
||||
- name: Checkout screenshots
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.SCREENSHOTS_REPO }}
|
||||
ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
|
||||
|
@ -100,7 +103,7 @@ jobs:
|
|||
path: screenshots
|
||||
|
||||
- name: Checkout private keys
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.PRIVATE_REPO }}
|
||||
ssh-key: ${{ secrets.PRIVATE_SSH_KEY }}
|
||||
|
@ -121,22 +124,22 @@ jobs:
|
|||
shell: bash
|
||||
working-directory: android
|
||||
run: |
|
||||
gradle bundleGoogleRelease publishGoogleReleaseBundle
|
||||
./gradlew bundleGoogleRelease publishGoogleReleaseBundle
|
||||
if: ${{ matrix.flavor == 'google' }}
|
||||
|
||||
- name: Compile and upload to Huawei AppGallery
|
||||
shell: bash
|
||||
working-directory: android
|
||||
run: |
|
||||
gradle bundleHuaweiRelease
|
||||
gradle publishHuaweiAppGalleryHuaweiRelease
|
||||
./gradlew bundleHuaweiRelease
|
||||
./gradlew publishHuaweiAppGalleryHuaweiRelease
|
||||
if: ${{ matrix.flavor == 'huawei' }}
|
||||
|
||||
- name: Compile universal APK
|
||||
shell: bash
|
||||
working-directory: android
|
||||
run: |
|
||||
gradle assembleWebRelease
|
||||
./gradlew assembleWebRelease
|
||||
if: ${{ matrix.flavor == 'web' }}
|
||||
|
||||
- name: Prepare release notes
|
||||
|
@ -150,7 +153,7 @@ jobs:
|
|||
echo ""
|
||||
echo "sha256sum:"
|
||||
echo -e '\n```'
|
||||
(cd ./android/build/outputs/apk/web/release/ && sha256sum OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk) | tr -d '\n'
|
||||
(cd ./android/app/build/outputs/apk/web/release/ && sha256sum OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk) | tr -d '\n'
|
||||
echo -e '\n```'
|
||||
} > ${{ runner.temp }}/release-notes.txt
|
||||
|
||||
|
@ -163,5 +166,5 @@ jobs:
|
|||
name: ${{ needs.tag.outputs.tag }}
|
||||
tag_name: ${{ needs.tag.outputs.tag }}
|
||||
discussion_category_name: 'Announcements'
|
||||
files: ./android/build/outputs/apk/web/release/OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk
|
||||
files: ./android/app/build/outputs/apk/web/release/OrganicMaps-${{ needs.tag.outputs.code }}-web-release.apk
|
||||
fail_on_unmatched_files: true
|
||||
|
|
2
.github/workflows/appstream-check.yaml
vendored
|
@ -12,7 +12,7 @@ jobs:
|
|||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install appstream validator
|
||||
shell: bash
|
||||
|
|
34
.github/workflows/cleanup_caches.yml
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
|
||||
name: Cleanup caches by a branch
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cleanup
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh extension install actions/gh-actions-cache
|
||||
|
||||
REPO=${{ github.repository }}
|
||||
BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge"
|
||||
|
||||
echo "Fetching list of cache key"
|
||||
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH | cut -f 1 )
|
||||
|
||||
## Setting this to not fail the workflow while deleting cache keys.
|
||||
set +e
|
||||
echo "Deleting caches..."
|
||||
for cacheKey in $cacheKeysForPR
|
||||
do
|
||||
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
|
||||
done
|
||||
echo "Done"
|
143
.github/workflows/coverage-check.yaml
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
name: Coverage Report
|
||||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- labeled
|
||||
- unlabeled
|
||||
|
||||
# Cancels previous jobs if the same branch or PR was updated again.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-coverage-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
should-run-check:
|
||||
name: Should run coverage
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
run-from-pr: ${{ steps.run-from-pr.outputs.run-from-pr }}
|
||||
manually-triggered: ${{ steps.manually-triggered.outputs.manually-triggered }}
|
||||
steps:
|
||||
- name: Check if PR has 'Coverage' label
|
||||
id: run-from-pr
|
||||
if: github.event_name == 'pull_request'
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
LABEL_NAME="Coverage"
|
||||
LABELS=$(gh pr view https://github.com/$GITHUB_REPOSITORY/pull/$PR_NUMBER --json labels)
|
||||
if echo "$LABELS" | jq -e '.labels[].name' | grep -q "$LABEL_NAME"; then
|
||||
echo "run-from-pr=true" >> $GITHUB_OUTPUT
|
||||
echo "'Coverage' label found in PR."
|
||||
fi
|
||||
- name: Check if manually triggered
|
||||
id: manually-triggered
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: echo "manually-triggered=true" >> $GITHUB_OUTPUT
|
||||
|
||||
coverage:
|
||||
needs: should-run-check
|
||||
name: Generate coverage report
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ needs.should-run-check.outputs.run-from-pr == 'true' || needs.should-run-check.outputs.manually-triggered == 'true'}}
|
||||
steps:
|
||||
- name: Free disk space by removing .NET, Android and Haskell
|
||||
shell: bash
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100 # enough to get all commits for the current day
|
||||
|
||||
- name: Parallel submodules checkout
|
||||
shell: bash
|
||||
run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20))
|
||||
|
||||
- name: Install build tools and dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt update -y
|
||||
sudo apt install -y \
|
||||
ninja-build \
|
||||
libgl1-mesa-dev \
|
||||
libglvnd-dev \
|
||||
qt6-base-dev \
|
||||
libqt6svg6-dev \
|
||||
qt6-positioning-dev \
|
||||
libqt6positioning6-plugins \
|
||||
libqt6positioning6 \
|
||||
llvm
|
||||
pip install gcovr
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: ./configure.sh
|
||||
|
||||
- name: Configure ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ github.workflow }}-coverage
|
||||
|
||||
- name: CMake
|
||||
shell: bash
|
||||
env:
|
||||
CC: clang-14
|
||||
CXX: clang++-14
|
||||
CMAKE_C_COMPILER_LAUNCHER: ccache
|
||||
CMAKE_CXX_COMPILER_LAUNCHER: ccache
|
||||
# -g1 should slightly reduce build time.
|
||||
run: |
|
||||
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug \
|
||||
-DCMAKE_CXX_FLAGS=-g1 -DCOVERAGE_REPORT=ON
|
||||
|
||||
- name: Compile
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: ninja
|
||||
|
||||
- name: Tests
|
||||
shell: bash
|
||||
working-directory: build
|
||||
env:
|
||||
# drape_tests - requires X Window
|
||||
# generator_integration_tests - https://github.com/organicmaps/organicmaps/issues/225
|
||||
# opening_hours_integration_tests - https://github.com/organicmaps/organicmaps/issues/219
|
||||
# opening_hours_supported_features_tests - https://github.com/organicmaps/organicmaps/issues/219
|
||||
# routing_integration_tests - https://github.com/organicmaps/organicmaps/issues/221
|
||||
# shaders_tests - https://github.com/organicmaps/organicmaps/issues/223
|
||||
# world_feed_integration_tests - https://github.com/organicmaps/organicmaps/issues/215
|
||||
CTEST_EXCLUDE_REGEX: "drape_tests|generator_integration_tests|opening_hours_integration_tests|opening_hours_supported_features_tests|routing_benchmarks|routing_integration_tests|routing_quality_tests|search_quality_tests|storage_integration_tests|shaders_tests|world_feed_integration_tests"
|
||||
run: |
|
||||
sudo locale-gen en_US
|
||||
sudo locale-gen en_US.UTF-8
|
||||
sudo locale-gen es_ES
|
||||
sudo locale-gen es_ES.UTF-8
|
||||
sudo locale-gen fr_FR
|
||||
sudo locale-gen fr_FR.UTF-8
|
||||
sudo locale-gen ru_RU
|
||||
sudo locale-gen ru_RU.UTF-8
|
||||
sudo update-locale
|
||||
ctest -L "omim-test" -E "$CTEST_EXCLUDE_REGEX" --output-on-failure
|
||||
|
||||
- name: Run coverage report generation
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake --build . --target omim_coverage
|
||||
cat coverage_report/summary.txt
|
||||
|
||||
- name: Archive the coverage report
|
||||
working-directory: build/coverage_report
|
||||
run: zip -r coverage_report.zip html/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: build/coverage_report/coverage_report.zip
|
23
.github/workflows/ios-beta.yaml
vendored
|
@ -19,6 +19,11 @@ on:
|
|||
- docs/**
|
||||
- generator/**
|
||||
- packaging/**
|
||||
- platform/*_android*
|
||||
- platform/*_linux*
|
||||
- platform/*_mac*
|
||||
- platform/*qt*
|
||||
- platform/*_win*
|
||||
- pyhelpers/**
|
||||
- qt*/**
|
||||
- skin_generator/**
|
||||
|
@ -28,8 +33,9 @@ on:
|
|||
jobs:
|
||||
ios-beta:
|
||||
name: Apple TestFlight
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
|
||||
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
|
||||
LANGUAGE: en_US.UTF-8
|
||||
LC_ALL: en_US.UTF-8
|
||||
|
@ -39,7 +45,7 @@ jobs:
|
|||
shell: bash
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100 # enough to get all commits for the current day
|
||||
|
||||
|
@ -47,7 +53,7 @@ jobs:
|
|||
run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20))
|
||||
|
||||
- name: Checkout private keys
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.PRIVATE_REPO }}
|
||||
ssh-key: ${{ secrets.PRIVATE_SSH_KEY }}
|
||||
|
@ -60,7 +66,16 @@ jobs:
|
|||
rm -rf ./private.git
|
||||
|
||||
- name: Compile and upload to TestFlight
|
||||
run: ./fastlane.sh upload_testflight
|
||||
run: |
|
||||
echo "IOS_VERSION=$(tools/unix/version.sh ios_version)-$(tools/unix/version.sh ios_build)" >> "$GITHUB_ENV"
|
||||
./fastlane.sh upload_testflight
|
||||
env:
|
||||
APPSTORE_CERTIFICATE_PASSWORD: '${{ secrets.APPSTORE_CERTIFICATE_PASSWORD }}'
|
||||
working-directory: xcode
|
||||
|
||||
- name: Upload ipa and DSYMs artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ipa and DSYM archive ${{ env.IOS_VERSION }}
|
||||
path: xcode/build/*
|
||||
if-no-files-found: error
|
||||
|
|
2
.github/workflows/ios-check-metadata.yaml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check metadata
|
||||
run: ./tools/python/check_store_metadata.py ios
|
||||
|
|
24
.github/workflows/ios-check.yaml
vendored
|
@ -1,6 +1,9 @@
|
|||
name: iOS Check
|
||||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- .gitignore
|
||||
|
@ -18,6 +21,11 @@ on:
|
|||
- generator/**
|
||||
- iphone/metadata/**
|
||||
- packaging/**
|
||||
- platform/*_android*
|
||||
- platform/*_linux*
|
||||
- platform/*_mac*
|
||||
- platform/*qt*
|
||||
- platform/*_win*
|
||||
- pyhelpers/**
|
||||
- qt*/**
|
||||
- skin_generator/**
|
||||
|
@ -27,8 +35,9 @@ on:
|
|||
jobs:
|
||||
ios-check:
|
||||
name: Build iOS
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
|
||||
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
|
||||
LANGUAGE: en_US.UTF-8
|
||||
LC_ALL: en_US.UTF-8
|
||||
|
@ -36,9 +45,14 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
buildType: [Debug, Release]
|
||||
# Cancels previous jobs if the same branch or PR was updated again.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ matrix.buildType }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Parallel submodules checkout
|
||||
shell: bash
|
||||
|
@ -48,11 +62,17 @@ jobs:
|
|||
shell: bash
|
||||
run: ./configure.sh
|
||||
|
||||
- name: Configure ccache
|
||||
uses: mikehardy/buildcache-action@v2.1.0
|
||||
with:
|
||||
cache_key: ${{ github.workflow }}-${{ matrix.buildType }}
|
||||
|
||||
- name: Compile
|
||||
shell: bash
|
||||
# Check for compilation errors.
|
||||
run: |
|
||||
xcodebuild \
|
||||
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
|
||||
-workspace xcode/omim.xcworkspace \
|
||||
-scheme OMaps \
|
||||
-configuration ${{ matrix.buildType }} build \
|
||||
|
|
11
.github/workflows/ios-release.yaml
vendored
|
@ -5,18 +5,19 @@ on:
|
|||
jobs:
|
||||
ios-release:
|
||||
name: iOS Release
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
|
||||
LANG: en_US.UTF-8 # Fastlane complains that the terminal is using ASCII.
|
||||
LANGUAGE: en_US.UTF-8
|
||||
LC_ALL: en_US.UTF-8
|
||||
environment: production
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Checkout private keys
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.PRIVATE_REPO }}
|
||||
ssh-key: ${{ secrets.PRIVATE_SSH_KEY }}
|
||||
|
@ -31,7 +32,7 @@ jobs:
|
|||
rm -rf ./private.git
|
||||
|
||||
- name: Checkout screenshots
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.SCREENSHOTS_REPO }}
|
||||
ssh-key: ${{ secrets.SCREENSHOTS_SSH_KEY }}
|
||||
|
@ -39,7 +40,7 @@ jobs:
|
|||
path: screenshots
|
||||
|
||||
- name: Checkout keywords
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.KEYWORDS_REPO }}
|
||||
ssh-key: ${{ secrets.KEYWORDS_SSH_KEY }}
|
||||
|
|
115
.github/workflows/linux-check.yaml
vendored
|
@ -1,6 +1,9 @@
|
|||
name: Linux Check
|
||||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- .gitignore
|
||||
|
@ -15,19 +18,25 @@ on:
|
|||
- data/strings/**
|
||||
- docs/**
|
||||
- packaging/**
|
||||
- platform/*apple*
|
||||
- platform/*_android*
|
||||
- platform/*_ios*
|
||||
- platform/*_mac*
|
||||
- platform/*_win*
|
||||
- pyhelpers/**
|
||||
- tools/**
|
||||
- '!tools/python/run_desktop_tests.py'
|
||||
- '!tools/python/testserver.py'
|
||||
- '!tools/python/SiblingKiller.py'
|
||||
- '!tools/python/test_server/**'
|
||||
- xcode/**
|
||||
|
||||
jobs:
|
||||
linux-no-unity:
|
||||
name: Linux no unity build
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# Cancels previous jobs if the same branch or PR was updated again.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-no-unity-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Free disk space by removing .NET, Android and Haskell
|
||||
shell: bash
|
||||
|
@ -35,7 +44,7 @@ jobs:
|
|||
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100 # enough to get all commits for the current day
|
||||
|
||||
|
@ -49,21 +58,34 @@ jobs:
|
|||
sudo apt update -y
|
||||
sudo apt install -y \
|
||||
ninja-build \
|
||||
qtbase5-dev \
|
||||
libqt5svg5-dev
|
||||
libgl1-mesa-dev \
|
||||
libglvnd-dev \
|
||||
qt6-base-dev \
|
||||
libqt6svg6-dev \
|
||||
qt6-positioning-dev \
|
||||
libqt6positioning6-plugins \
|
||||
libqt6positioning6
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: ./configure.sh
|
||||
|
||||
- name: Configure ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ github.workflow }}-no-unity
|
||||
|
||||
- name: CMake
|
||||
shell: bash
|
||||
env:
|
||||
CC: clang-14
|
||||
CXX: clang++-14
|
||||
CMAKE_C_COMPILER_LAUNCHER: ccache
|
||||
CMAKE_CXX_COMPILER_LAUNCHER: ccache
|
||||
# -g1 should slightly reduce build time.
|
||||
run: |
|
||||
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-g1 -DUNITY_DISABLE=ON
|
||||
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug \
|
||||
-DCMAKE_CXX_FLAGS=-g1 -DUNITY_DISABLE=ON
|
||||
|
||||
- name: Compile
|
||||
shell: bash
|
||||
|
@ -78,6 +100,10 @@ jobs:
|
|||
matrix:
|
||||
compiler: [{ CXX: g++-12, CC: gcc-12 }, { CXX: clang++-14, CC: clang-14 }]
|
||||
CMAKE_BUILD_TYPE: [Debug, RelWithDebInfo]
|
||||
# Cancels previous jobs if the same branch or PR was updated again.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-unity-${{ matrix.compiler.CC }}-${{ matrix.CMAKE_BUILD_TYPE }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Free disk space by removing .NET, Android and Haskell
|
||||
|
@ -86,7 +112,7 @@ jobs:
|
|||
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Parallel submodules checkout
|
||||
shell: bash
|
||||
|
@ -100,58 +126,61 @@ jobs:
|
|||
g++-12 \
|
||||
gcc-12 \
|
||||
ninja-build \
|
||||
qtbase5-dev \
|
||||
libqt5svg5-dev
|
||||
libgl1-mesa-dev \
|
||||
libglvnd-dev \
|
||||
qt6-base-dev \
|
||||
libqt6svg6-dev \
|
||||
qt6-positioning-dev \
|
||||
libqt6positioning6-plugins \
|
||||
libqt6positioning6
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: ./configure.sh
|
||||
|
||||
- name: Configure ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ github.workflow }}-unity-${{ matrix.compiler.CC }}-${{ matrix.CMAKE_BUILD_TYPE }}
|
||||
|
||||
- name: CMake
|
||||
shell: bash
|
||||
env:
|
||||
CC: ${{ matrix.compiler.CC }}
|
||||
CXX: ${{ matrix.compiler.CXX }}
|
||||
CMAKE_C_COMPILER_LAUNCHER: ccache
|
||||
CMAKE_CXX_COMPILER_LAUNCHER: ccache
|
||||
# -g1 should slightly reduce build time.
|
||||
run: |
|
||||
echo "Building ${{ matrix.CMAKE_BUILD_TYPE }}"
|
||||
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.CMAKE_BUILD_TYPE }} -DCMAKE_C_FLAGS=-g1 -DCMAKE_CXX_FLAGS=-g1
|
||||
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.CMAKE_BUILD_TYPE }} \
|
||||
-DCMAKE_C_FLAGS=-g1 -DCMAKE_CXX_FLAGS=-g1
|
||||
|
||||
- name: Compile
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: ninja
|
||||
|
||||
- name: Checkout world_feed_integration_tests_data
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: organicmaps/world_feed_integration_tests_data
|
||||
path: data/world_feed_integration_tests_data
|
||||
|
||||
- name: Tests
|
||||
shell: bash
|
||||
# generator_integration_tests - https://github.com/organicmaps/organicmaps/issues/225
|
||||
# routing_integration_tests - https://github.com/organicmaps/organicmaps/issues/221
|
||||
# routing_quality_tests - https://github.com/organicmaps/organicmaps/issues/215
|
||||
# drape_tests - requires X Window
|
||||
|
||||
# Separate run of OH boost-based test
|
||||
working-directory: build
|
||||
env:
|
||||
# drape_tests - requires X Window
|
||||
# generator_integration_tests - https://github.com/organicmaps/organicmaps/issues/225
|
||||
# opening_hours_integration_tests - https://github.com/organicmaps/organicmaps/issues/219
|
||||
# opening_hours_supported_features_tests - https://github.com/organicmaps/organicmaps/issues/219
|
||||
# routing_integration_tests - https://github.com/organicmaps/organicmaps/issues/221
|
||||
# shaders_tests - https://github.com/organicmaps/organicmaps/issues/223
|
||||
# world_feed_integration_tests - https://github.com/organicmaps/organicmaps/issues/215
|
||||
CTEST_EXCLUDE_REGEX: "drape_tests|generator_integration_tests|opening_hours_integration_tests|opening_hours_supported_features_tests|routing_benchmarks|routing_integration_tests|routing_quality_tests|search_quality_tests|storage_integration_tests|shaders_tests|world_feed_integration_tests"
|
||||
run: |
|
||||
./build/opening_hours_tests |
|
||||
./tools/python/run_desktop_tests.py \
|
||||
-f ./build \
|
||||
-u ./data \
|
||||
-d ./data \
|
||||
-e generator_integration_tests \
|
||||
-e routing_integration_tests \
|
||||
-e routing_quality_tests \
|
||||
-e search_quality_tests \
|
||||
-e world_feed_integration_tests \
|
||||
-e drape_tests \
|
||||
-e shaders_tests \
|
||||
\
|
||||
-e opening_hours_tests \
|
||||
-e opening_hours_integration_tests \
|
||||
-e routing_consistency_tests \
|
||||
-e opening_hours_supported_features_tests \
|
||||
-e storage_integration_tests \
|
||||
sudo locale-gen en_US
|
||||
sudo locale-gen en_US.UTF-8
|
||||
sudo locale-gen es_ES
|
||||
sudo locale-gen es_ES.UTF-8
|
||||
sudo locale-gen fr_FR
|
||||
sudo locale-gen fr_FR.UTF-8
|
||||
sudo locale-gen ru_RU
|
||||
sudo locale-gen ru_RU.UTF-8
|
||||
sudo update-locale
|
||||
ctest -L "omim-test" -E "$CTEST_EXCLUDE_REGEX" --output-on-failure
|
||||
|
|
74
.github/workflows/macos-check.yaml
vendored
|
@ -1,6 +1,9 @@
|
|||
name: macOS Check
|
||||
on:
|
||||
workflow_dispatch: # Manual trigger
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- .gitignore
|
||||
|
@ -15,28 +18,35 @@ on:
|
|||
- data/strings/**
|
||||
- docs/**
|
||||
- packaging/**
|
||||
- platform/*_android*
|
||||
- platform/*_ios*
|
||||
- platform/*_linux*
|
||||
- platform/*_win*
|
||||
- pyhelpers/**
|
||||
- tools/**
|
||||
- '!tools/python/run_desktop_tests.py'
|
||||
- '!tools/python/testserver.py'
|
||||
- '!tools/python/SiblingKiller.py'
|
||||
- '!tools/python/test_server/**'
|
||||
- xcode/**
|
||||
|
||||
jobs:
|
||||
macos-matrix:
|
||||
name: macOS builds and tests
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
env:
|
||||
DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
|
||||
HOMEBREW_NO_ANALYTICS: 1
|
||||
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
CMAKE_BUILD_TYPE: [Debug, RelWithDebInfo]
|
||||
# Cancels previous jobs if the same branch or PR was updated again.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ matrix.CMAKE_BUILD_TYPE }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Parallel submodules checkout
|
||||
shell: bash
|
||||
|
@ -45,53 +55,43 @@ jobs:
|
|||
- name: Install build tools and dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
brew install ninja qt@5
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ninja qt@6
|
||||
|
||||
- name: Configure
|
||||
shell: bash
|
||||
run: ./configure.sh
|
||||
|
||||
- name: Configure ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ matrix.CMAKE_BUILD_TYPE }}
|
||||
|
||||
- name: CMake
|
||||
shell: bash
|
||||
env:
|
||||
CMAKE_C_COMPILER_LAUNCHER: ccache
|
||||
CMAKE_CXX_COMPILER_LAUNCHER: ccache
|
||||
run: |
|
||||
echo "Building ${{ matrix.CMAKE_BUILD_TYPE }}"
|
||||
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.CMAKE_BUILD_TYPE }} -DCMAKE_C_FLAGS=-g1 -DCMAKE_CXX_FLAGS=-g1
|
||||
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.CMAKE_BUILD_TYPE }} \
|
||||
-DCMAKE_C_FLAGS=-g1 -DCMAKE_CXX_FLAGS=-g1
|
||||
|
||||
- name: Compile
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: ninja
|
||||
|
||||
- name: Checkout world_feed_integration_tests_data
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: organicmaps/world_feed_integration_tests_data
|
||||
path: data/world_feed_integration_tests_data
|
||||
|
||||
- name: Tests
|
||||
shell: bash
|
||||
# generator_integration_tests - https://github.com/organicmaps/organicmaps/issues/225
|
||||
# # routing_integration_tests - https://github.com/organicmaps/organicmaps/issues/221
|
||||
# routing_quality_tests - https://github.com/organicmaps/organicmaps/issues/215
|
||||
# drape_tests - requires X Window
|
||||
|
||||
# Separate run of OH boost-based test
|
||||
working-directory: build
|
||||
env:
|
||||
# drape_tests - requires X Window
|
||||
# generator_integration_tests - https://github.com/organicmaps/organicmaps/issues/225
|
||||
# opening_hours_integration_tests - https://github.com/organicmaps/organicmaps/issues/219
|
||||
# opening_hours_supported_features_tests - https://github.com/organicmaps/organicmaps/issues/219
|
||||
# routing_integration_tests - https://github.com/organicmaps/organicmaps/issues/221
|
||||
# shaders_tests - https://github.com/organicmaps/organicmaps/issues/223
|
||||
# world_feed_integration_tests - https://github.com/organicmaps/organicmaps/issues/215
|
||||
CTEST_EXCLUDE_REGEX: "drape_tests|generator_integration_tests|opening_hours_integration_tests|opening_hours_supported_features_tests|routing_benchmarks|routing_integration_tests|routing_quality_tests|search_quality_tests|storage_integration_tests|shaders_tests|world_feed_integration_tests"
|
||||
run: |
|
||||
./build/opening_hours_tests |
|
||||
./tools/python/run_desktop_tests.py \
|
||||
-f ./build \
|
||||
-u ./data \
|
||||
-d ./data \
|
||||
-e generator_integration_tests \
|
||||
-e routing_integration_tests \
|
||||
-e routing_quality_tests \
|
||||
-e search_quality_tests \
|
||||
-e world_feed_integration_tests \
|
||||
-e drape_tests \
|
||||
-e shaders_tests \
|
||||
\
|
||||
-e opening_hours_tests \
|
||||
-e opening_hours_integration_tests \
|
||||
-e routing_consistency_tests \
|
||||
-e opening_hours_supported_features_tests \
|
||||
-e storage_integration_tests
|
||||
ctest -L "omim-test" -E "$CTEST_EXCLUDE_REGEX" --output-on-failure
|
||||
|
|
4
.github/workflows/strings-check.yaml
vendored
|
@ -14,8 +14,8 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3'
|
||||
|
||||
|
|
4
.gitignore
vendored
|
@ -84,6 +84,7 @@ data/[0-9][0-9][0-9][0-9][0-9][0-9]
|
|||
data/gps_track.dat
|
||||
# temporary files for downloader
|
||||
data/settings.ini
|
||||
data/world_feed_integration_tests_data
|
||||
|
||||
# benchmark results
|
||||
data/benchmarks/*.trace
|
||||
|
@ -127,6 +128,7 @@ tizen/*/crash-info/*
|
|||
.private_repository_url
|
||||
.private_repository_branch
|
||||
private.h
|
||||
# ignore old android secrets during the transition period to the new project structure
|
||||
android/release.keystore
|
||||
android/secure.properties
|
||||
android/libnotify.properties
|
||||
|
@ -136,7 +138,7 @@ android/firebase-app-distribution.json
|
|||
android/firebase-test-lab.json
|
||||
android/huawei-appgallery.json
|
||||
android/res/xml/network_security_config.xml
|
||||
server
|
||||
./server/
|
||||
iphone/Maps/app.omaps/
|
||||
|
||||
*.li
|
||||
|
|
11
.gitmodules
vendored
|
@ -37,7 +37,7 @@
|
|||
url = https://github.com/unicode-org/icu.git
|
||||
[submodule "3party/freetype/freetype"]
|
||||
path = 3party/freetype/freetype
|
||||
url = https://github.com/freetype/freetype.git
|
||||
url = https://github.com/organicmaps/freetype.git
|
||||
[submodule "3party/googletest"]
|
||||
path = 3party/googletest
|
||||
url = https://github.com/google/googletest.git
|
||||
|
@ -53,3 +53,12 @@
|
|||
[submodule "3party/gflags"]
|
||||
path = 3party/gflags
|
||||
url = https://github.com/gflags/gflags
|
||||
[submodule "3party/fast_obj"]
|
||||
path = 3party/fast_obj
|
||||
url = https://github.com/thisistherk/fast_obj
|
||||
[submodule "3party/harfbuzz/harfbuzz"]
|
||||
path = 3party/harfbuzz/harfbuzz
|
||||
url = https://github.com/harfbuzz/harfbuzz.git
|
||||
[submodule "3party/utfcpp"]
|
||||
path = 3party/utfcpp
|
||||
url = https://github.com/nemtrif/utfcpp.git
|
||||
|
|
63
3party/CMakeLists.txt
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Fixes CMake deprecation warning:
|
||||
# Compatibility with CMake < 3.5 will be removed from a future version of CMake.
|
||||
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "" FORCE)
|
||||
|
||||
if (WITH_SYSTEM_PROVIDED_3PARTY)
|
||||
set(GFLAGS_USE_TARGET_NAMESPACE ON)
|
||||
find_package(gflags REQUIRED GLOBAL)
|
||||
else()
|
||||
# Configure expat library.
|
||||
# Suppress "Policy CMP0077 is not set: option() honors normal variables"
|
||||
# for the expat options below.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
set(EXPAT_BUILD_TOOLS OFF)
|
||||
set(EXPAT_BUILD_EXAMPLES OFF)
|
||||
set(EXPAT_BUILD_TESTS OFF)
|
||||
set(EXPAT_BUILD_DOCS OFF)
|
||||
set(EXPAT_BUILD_PKGCONFIG OFF)
|
||||
set(EXPAT_ENABLE_INSTALL OFF)
|
||||
set(EXPAT_SHARED_LIBS OFF)
|
||||
add_subdirectory(expat/expat)
|
||||
|
||||
# Configure Jansson library.
|
||||
set(JANSSON_BUILD_DOCS OFF)
|
||||
set(JANSSON_BUILD_MAN OFF)
|
||||
set(JANSSON_EXAMPLES OFF)
|
||||
set(JANSSON_INSTALL OFF)
|
||||
set(JANSSON_WITHOUT_TESTS ON)
|
||||
add_subdirectory(jansson/jansson/)
|
||||
target_include_directories(jansson INTERFACE "${PROJECT_BINARY_DIR}/3party/jansson/jansson/include")
|
||||
|
||||
# Add gflags library.
|
||||
add_subdirectory(gflags)
|
||||
target_compile_options(gflags_nothreads_static PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wno-subobject-linkage>)
|
||||
|
||||
# Add pugixml library.
|
||||
add_subdirectory(pugixml)
|
||||
|
||||
# Add protobuf library.
|
||||
add_subdirectory(protobuf)
|
||||
endif()
|
||||
|
||||
add_subdirectory(agg)
|
||||
add_subdirectory(bsdiff-courgette)
|
||||
|
||||
if (NOT LINUX_DETECTED)
|
||||
add_subdirectory(freetype)
|
||||
add_subdirectory(icu)
|
||||
endif()
|
||||
|
||||
add_subdirectory(harfbuzz)
|
||||
add_subdirectory(liboauthcpp)
|
||||
add_subdirectory(minizip)
|
||||
add_subdirectory(open-location-code)
|
||||
add_subdirectory(opening_hours)
|
||||
add_subdirectory(sdf_image)
|
||||
add_subdirectory(stb_image)
|
||||
add_subdirectory(succinct)
|
||||
|
||||
add_subdirectory(vulkan_wrapper)
|
||||
|
||||
if (PLATFORM_DESKTOP)
|
||||
add_subdirectory(libtess2)
|
||||
endif()
|
|
@ -422,7 +422,7 @@ namespace agg
|
|||
inline bool is_close(unsigned c)
|
||||
{
|
||||
return (c & ~(path_flags_cw | path_flags_ccw)) ==
|
||||
(path_cmd_end_poly | path_flags_close);
|
||||
(unsigned(path_cmd_end_poly) | path_flags_close);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------is_next_poly
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace agg
|
|||
*x = m_vertices[m_vertex];
|
||||
*y = m_vertices[m_vertex + 1];
|
||||
m_vertex += 2;
|
||||
return (m_vertex == 2) ? path_cmd_move_to : m_cmd;
|
||||
return (m_vertex == 2) ? unsigned(path_cmd_move_to) : m_cmd;
|
||||
}
|
||||
|
||||
// Supplemantary functions. num_vertices() actually returns doubled
|
||||
|
|
|
@ -429,7 +429,7 @@ namespace agg
|
|||
static value_type luminance(const rgba& c)
|
||||
{
|
||||
// Calculate grayscale value as per ITU-R BT.709.
|
||||
return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
|
||||
return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * double(base_mask)));
|
||||
}
|
||||
|
||||
static value_type luminance(const rgba16& c)
|
||||
|
@ -530,13 +530,13 @@ namespace agg
|
|||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return double(a) / base_mask;
|
||||
return double(a) / double(base_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(uround(a * base_mask));
|
||||
return value_type(uround(a * double(base_mask)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -674,7 +674,7 @@ namespace agg
|
|||
else
|
||||
{
|
||||
calc_type v_ = (calc_type(v) * base_mask) / a;
|
||||
v = value_type((v_ > base_mask) ? base_mask : v_);
|
||||
v = value_type((v_ > base_mask) ? calc_type(base_mask) : v_);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
|
@ -684,7 +684,7 @@ namespace agg
|
|||
self_type gradient(self_type c, double k) const
|
||||
{
|
||||
self_type ret;
|
||||
calc_type ik = uround(k * base_scale);
|
||||
calc_type ik = uround(k * double(base_scale));
|
||||
ret.v = lerp(v, c.v, ik);
|
||||
ret.a = lerp(a, c.a, ik);
|
||||
return ret;
|
||||
|
@ -921,7 +921,7 @@ namespace agg
|
|||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
||||
{
|
||||
return value_type(a * b / cover_mask);
|
||||
return value_type(a * value_type(b) / value_type(cover_mask));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
|
@ -323,13 +323,13 @@ namespace agg
|
|||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return double(a) / base_mask;
|
||||
return double(a) / double(base_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(uround(a * base_mask));
|
||||
return value_type(uround(a * double(base_mask)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -701,13 +701,13 @@ namespace agg
|
|||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE double to_double(value_type a)
|
||||
{
|
||||
return double(a) / base_mask;
|
||||
return double(a) / double(base_mask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type from_double(double a)
|
||||
{
|
||||
return value_type(uround(a * base_mask));
|
||||
return value_type(uround(a * double(base_mask)));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
@ -888,7 +888,7 @@ namespace agg
|
|||
AGG_INLINE self_type gradient(const self_type& c, double k) const
|
||||
{
|
||||
self_type ret;
|
||||
calc_type ik = uround(k * base_mask);
|
||||
calc_type ik = uround(k * double(base_mask));
|
||||
ret.r = lerp(r, c.r, ik);
|
||||
ret.g = lerp(g, c.g, ik);
|
||||
ret.b = lerp(b, c.b, ik);
|
||||
|
@ -1120,7 +1120,7 @@ namespace agg
|
|||
//--------------------------------------------------------------------
|
||||
static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
|
||||
{
|
||||
return value_type(a * b / cover_mask);
|
||||
return value_type(a * double(b) / double(cover_mask));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
|
@ -98,6 +98,7 @@ namespace agg
|
|||
m_markers.remove_all();
|
||||
m_last_cmd = m_source->vertex(&m_start_x, &m_start_y);
|
||||
m_status = accumulate;
|
||||
[[fallthrough]];
|
||||
|
||||
case accumulate:
|
||||
if(is_stop(m_last_cmd)) return path_cmd_stop;
|
||||
|
@ -137,6 +138,7 @@ namespace agg
|
|||
}
|
||||
m_generator.rewind(0);
|
||||
m_status = generate;
|
||||
[[fallthrough]];
|
||||
|
||||
case generate:
|
||||
cmd = m_generator.vertex(x, y);
|
||||
|
|
|
@ -398,7 +398,7 @@ namespace agg
|
|||
if(m_closed && !m_stop)
|
||||
{
|
||||
m_stop = true;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
return unsigned(path_cmd_end_poly) | path_flags_close;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ namespace agg
|
|||
if(m_closed && !m_stop)
|
||||
{
|
||||
m_stop = true;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
return unsigned(path_cmd_end_poly) | path_flags_close;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
|
@ -525,7 +525,7 @@ namespace agg
|
|||
if(m_closed && !m_stop)
|
||||
{
|
||||
m_stop = true;
|
||||
return path_cmd_end_poly | path_flags_close;
|
||||
return unsigned(path_cmd_end_poly) | path_flags_close;
|
||||
}
|
||||
return path_cmd_stop;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace agg
|
|||
|
||||
if (cover < cover_full)
|
||||
{
|
||||
double x = double(cover) / cover_full;
|
||||
double x = double(cover) / double(cover_full);
|
||||
c.r *= x;
|
||||
c.g *= x;
|
||||
c.b *= x;
|
||||
|
|
|
@ -659,7 +659,7 @@ namespace agg
|
|||
while(nb)
|
||||
{
|
||||
cell_ptr = *block_ptr++;
|
||||
i = (nb > cell_block_size) ? cell_block_size : nb;
|
||||
i = (nb > unsigned(cell_block_size)) ? unsigned(cell_block_size) : nb;
|
||||
nb -= i;
|
||||
while(i--)
|
||||
{
|
||||
|
@ -683,7 +683,7 @@ namespace agg
|
|||
while(nb)
|
||||
{
|
||||
cell_ptr = *block_ptr++;
|
||||
i = (nb > cell_block_size) ? cell_block_size : nb;
|
||||
i = (nb > unsigned(cell_block_size)) ? unsigned(cell_block_size) : nb;
|
||||
nb -= i;
|
||||
while(i--)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace agg
|
|||
}
|
||||
static int xi(int v) { return v; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int upscale(double v) { return iround(v * double(poly_subpixel_scale)); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace agg
|
|||
static int yi(int v) { return v; }
|
||||
static int upscale(double v)
|
||||
{
|
||||
return saturation<poly_max_coord>::iround(v * poly_subpixel_scale);
|
||||
return saturation<poly_max_coord>::iround(v * double(poly_subpixel_scale));
|
||||
}
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
@ -66,7 +66,7 @@ namespace agg
|
|||
}
|
||||
static int xi(int v) { return v * 3; }
|
||||
static int yi(int v) { return v; }
|
||||
static int upscale(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int upscale(double v) { return iround(v * double(poly_subpixel_scale)); }
|
||||
static int downscale(int v) { return v; }
|
||||
};
|
||||
|
||||
|
@ -78,8 +78,8 @@ namespace agg
|
|||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int xi(double v) { return iround(v * double(poly_subpixel_scale)); }
|
||||
static int yi(double v) { return iround(v * double(poly_subpixel_scale)); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
@ -92,8 +92,8 @@ namespace agg
|
|||
{
|
||||
return a * b / c;
|
||||
}
|
||||
static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
|
||||
static int yi(double v) { return iround(v * poly_subpixel_scale); }
|
||||
static int xi(double v) { return iround(v * double(poly_subpixel_scale) * 3); }
|
||||
static int yi(double v) { return iround(v * double(poly_subpixel_scale)); }
|
||||
static double upscale(double v) { return v; }
|
||||
static double downscale(int v) { return v / double(poly_subpixel_scale); }
|
||||
};
|
||||
|
|
|
@ -196,11 +196,11 @@ namespace agg
|
|||
|
||||
case end_poly1:
|
||||
m_status = m_prev_status;
|
||||
return path_cmd_end_poly | path_flags_close | path_flags_ccw;
|
||||
return unsigned(path_cmd_end_poly) | path_flags_close | path_flags_ccw;
|
||||
|
||||
case end_poly2:
|
||||
m_status = m_prev_status;
|
||||
return path_cmd_end_poly | path_flags_close | path_flags_cw;
|
||||
return unsigned(path_cmd_end_poly) | path_flags_close | path_flags_cw;
|
||||
|
||||
case stop:
|
||||
cmd = path_cmd_stop;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5002c2d6a2b5ed56a82128797828de95dab2ddba
|
||||
Subproject commit 564e2ac16907019696cdaba8a93e3588ec596062
|
1
3party/fast_obj
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 1a8060257a96401a9555a476bd13c3a87502c9b5
|
|
@ -1,7 +1,11 @@
|
|||
# TODO: Check if enabling it provides benefits.
|
||||
set(FT_DISABLE_HARFBUZZ ON)
|
||||
|
||||
add_subdirectory(freetype)
|
||||
|
||||
# Fix warning with ONE_PIXEL macro clash.
|
||||
target_compile_options(freetype PRIVATE -Wno-macro-redefined)
|
||||
|
||||
# Use ft2build.h from the current directory instead of the default.
|
||||
target_include_directories(freetype
|
||||
BEFORE PUBLIC
|
||||
|
@ -10,3 +14,4 @@ target_include_directories(freetype
|
|||
)
|
||||
|
||||
add_library(Freetype::Freetype ALIAS freetype)
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 4eb6cb8818057a022f97176b53738ee3098c8eb6
|
||||
Subproject commit e4586d960f339cf75e2e0b34aee30a0ed8353c0d
|
38
3party/harfbuzz/CMakeLists.txt
Normal file
|
@ -0,0 +1,38 @@
|
|||
project(harfbuzz)
|
||||
|
||||
set(SOURCES
|
||||
harfbuzz/src/harfbuzz.cc
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
harfbuzz/src
|
||||
)
|
||||
|
||||
# Keep these settigns in sync with xcode/harfbuzz project.
|
||||
target_compile_options(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
-fno-rtti
|
||||
-fno-exceptions
|
||||
-fno-threadsafe-statics
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
HAVE_FREETYPE=1
|
||||
# TODO: Enable later if necessary, and sync with xcode/harfbuzz project.
|
||||
#HAVE_ICU
|
||||
#$<$<BOOL:${APPLE}>:HAVE_CORETEXT>
|
||||
HAVE_ATEXIT
|
||||
HAVE_GETPAGESIZE
|
||||
HAVE_MMAP
|
||||
HAVE_MPROTECT
|
||||
HAVE_PTHREAD
|
||||
HAVE_SYSCONF
|
||||
HAVE_SYS_MMAN_H
|
||||
HAVE_UNISTD_H
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} Freetype::Freetype)
|
1
3party/harfbuzz/harfbuzz
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit e8eb1dc5ff695427abc137d3d15c4eec64ab6c78
|
|
@ -1 +1 @@
|
|||
Subproject commit 904cf62457de2440e8526deb75c95a3f7296f517
|
||||
Subproject commit 680f521746a3bd6a86f25f25ee50a62d88b489cf
|
|
@ -221,8 +221,7 @@ static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void fill_fopen_filefunc (pzlib_filefunc_def)
|
||||
zlib_filefunc_def* pzlib_filefunc_def;
|
||||
void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
|
||||
{
|
||||
pzlib_filefunc_def->zopen_file = fopen_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
|
|
|
@ -21,8 +21,6 @@ omim_add_library(${PROJECT_NAME} ${SRC})
|
|||
|
||||
target_include_directories(${PROJECT_NAME} INTERFACE .)
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-deprecated-copy)
|
||||
|
||||
omim_add_test_subdirectory(opening_hours_tests)
|
||||
omim_add_test_subdirectory(opening_hours_integration_tests)
|
||||
omim_add_test_subdirectory(opening_hours_supported_features_tests)
|
||||
|
|
|
@ -387,7 +387,7 @@ bool operator==(Timespan const & lhs, Timespan const & rhs)
|
|||
|
||||
return lhs.GetStart() == rhs.GetStart() &&
|
||||
lhs.GetEnd() == rhs.GetEnd() &&
|
||||
lhs.GetPeriod() == lhs.GetPeriod();
|
||||
lhs.GetPeriod() == rhs.GetPeriod();
|
||||
}
|
||||
|
||||
// NthWeekdayOfTheMonthEntry -----------------------------------------------------------------------
|
||||
|
|
|
@ -2,14 +2,9 @@ project(opening_hours_integration_tests)
|
|||
|
||||
set(SRC opening_hours_integration_tests.cpp)
|
||||
|
||||
omim_add_executable(${PROJECT_NAME} ${SRC})
|
||||
omim_add_test(${PROJECT_NAME} ${SRC} BOOST_TEST)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} opening_hours)
|
||||
# Silence boost::test warnings.
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-deprecated-declarations>
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-unused-but-set-variable>
|
||||
)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(COPY_CMD cp -u)
|
||||
|
|
|
@ -2,11 +2,6 @@ project(opening_hours_supported_features_tests)
|
|||
|
||||
set(SRC opening_hours_supported_features_tests.cpp)
|
||||
|
||||
omim_add_executable(${PROJECT_NAME} ${SRC})
|
||||
omim_add_test(${PROJECT_NAME} ${SRC} BOOST_TEST)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} opening_hours)
|
||||
# Silence boost::test warnings.
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-deprecated-declarations>
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-unused-but-set-variable>
|
||||
)
|
||||
|
|
|
@ -2,11 +2,6 @@ project(opening_hours_tests)
|
|||
|
||||
set(SRC opening_hours_tests.cpp)
|
||||
|
||||
omim_add_executable(${PROJECT_NAME} ${SRC})
|
||||
omim_add_test(${PROJECT_NAME} ${SRC} BOOST_TEST)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} opening_hours)
|
||||
# Silence boost::test warnings.
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-deprecated-declarations>
|
||||
$<$<CXX_COMPILER_ID:AppleClang>:-Wno-unused-but-set-variable>
|
||||
)
|
||||
|
|
|
@ -31,17 +31,17 @@ namespace osmoh
|
|||
|
||||
date_offset = ((lit('+')[_a = true] | lit('-')[_a = false])
|
||||
>> charset::no_case[wdays] >> day_offset)
|
||||
[bind(&DateOffset::SetWDayOffset, _val, _1),
|
||||
bind(&DateOffset::SetOffset, _val, _2),
|
||||
bind(&DateOffset::SetWDayOffsetPositive, _val, _a)]
|
||||
[(bind(&DateOffset::SetWDayOffset, _val, _1),
|
||||
bind(&DateOffset::SetOffset, _val, _2),
|
||||
bind(&DateOffset::SetWDayOffsetPositive, _val, _a))]
|
||||
| ((lit('+')[_a = true] | lit('-') [_a = false]) >> charset::no_case[wdays])
|
||||
[bind(&DateOffset::SetWDayOffset, _val, _1),
|
||||
bind(&DateOffset::SetWDayOffsetPositive, _val, _a)]
|
||||
[(bind(&DateOffset::SetWDayOffset, _val, _1),
|
||||
bind(&DateOffset::SetWDayOffsetPositive, _val, _a))]
|
||||
| day_offset [bind(&DateOffset::SetOffset, _val, _1)]
|
||||
;
|
||||
|
||||
date_left = (year >> charset::no_case[month]) [bind(&MonthDay::SetYear, _val, _1),
|
||||
bind(&MonthDay::SetMonth, _val, _2)]
|
||||
date_left = (year >> charset::no_case[month]) [(bind(&MonthDay::SetYear, _val, _1),
|
||||
bind(&MonthDay::SetMonth, _val, _2))]
|
||||
|
||||
| charset::no_case[month] [bind(&MonthDay::SetMonth, _val, _1)]
|
||||
;
|
||||
|
@ -50,10 +50,10 @@ namespace osmoh
|
|||
;
|
||||
|
||||
date_from = (date_left >> (daynum >> !(lit(':') >> qi::digit)))
|
||||
[_val = _1, bind(&MonthDay::SetDayNum, _val, _2)]
|
||||
| (year >> charset::no_case[lit("easter")]) [bind(&MonthDay::SetYear, _val, _1),
|
||||
bind(&MonthDay::SetVariableDate, _val,
|
||||
MonthDay::VariableDate::Easter)]
|
||||
[(_val = _1, bind(&MonthDay::SetDayNum, _val, _2))]
|
||||
| (year >> charset::no_case[lit("easter")]) [(bind(&MonthDay::SetYear, _val, _1),
|
||||
bind(&MonthDay::SetVariableDate, _val,
|
||||
MonthDay::VariableDate::Easter))]
|
||||
| charset::no_case[lit("easter")] [bind(&MonthDay::SetVariableDate, _val,
|
||||
MonthDay::VariableDate::Easter)]
|
||||
;
|
||||
|
@ -63,26 +63,26 @@ namespace osmoh
|
|||
;
|
||||
|
||||
date_from_with_offset = (date_from >> date_offset)
|
||||
[_val = _1, bind(&MonthDay::SetOffset, _val, _2)]
|
||||
[(_val = _1, bind(&MonthDay::SetOffset, _val, _2))]
|
||||
| date_from [_val = _1]
|
||||
;
|
||||
|
||||
date_to_with_offset = (date_to >> date_offset)
|
||||
[_val = _1, bind(&MonthDay::SetOffset, _val, _2)]
|
||||
[(_val = _1, bind(&MonthDay::SetOffset, _val, _2))]
|
||||
| date_to [_val = _1]
|
||||
;
|
||||
|
||||
monthday_range = (date_from_with_offset >> dash >> date_to_with_offset)
|
||||
[bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetEnd, _val, _2)]
|
||||
| (date_from_with_offset >> '+') [bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetPlus, _val, true)]
|
||||
[(bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetEnd, _val, _2))]
|
||||
| (date_from_with_offset >> '+') [(bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetPlus, _val, true))]
|
||||
| (date_left >> dash >> date_right >> '/' >> uint_)
|
||||
[bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetEnd, _val, _2),
|
||||
bind(&MonthdayRange::SetPeriod, _val, _3)]
|
||||
| (date_left >> lit("-") >> date_right) [bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetEnd, _val, _2)]
|
||||
[(bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetEnd, _val, _2),
|
||||
bind(&MonthdayRange::SetPeriod, _val, _3))]
|
||||
| (date_left >> lit("-") >> date_right) [(bind(&MonthdayRange::SetStart, _val, _1),
|
||||
bind(&MonthdayRange::SetEnd, _val, _2))]
|
||||
| date_from [bind(&MonthdayRange::SetStart, _val, _1)]
|
||||
| date_left [bind(&MonthdayRange::SetStart, _val, _1)]
|
||||
;
|
||||
|
|
|
@ -90,8 +90,8 @@ namespace parsing
|
|||
[bind(&RuleSequence::SetModifier, _r1, Modifier::Unknown)] >>
|
||||
-(comment [bind(&RuleSequence::SetModifierComment, _r1, _1)]))
|
||||
|
||||
| comment [bind(&RuleSequence::SetModifier, _r1, Modifier::Comment),
|
||||
bind(&RuleSequence::SetModifierComment, _r1, _1)]
|
||||
| comment [(bind(&RuleSequence::SetModifier, _r1, Modifier::Comment),
|
||||
bind(&RuleSequence::SetModifierComment, _r1, _1))]
|
||||
;
|
||||
|
||||
rule_sequence =
|
||||
|
|
|
@ -24,13 +24,13 @@ namespace osmoh
|
|||
using osmoh::Timespan;
|
||||
|
||||
hour_minutes =
|
||||
(hours >> lit(':') >> minutes) [bind(&HourMinutes::AddDuration, _val, _1),
|
||||
bind(&HourMinutes::AddDuration, _val, _2)]
|
||||
(hours >> lit(':') >> minutes) [(bind(&HourMinutes::AddDuration, _val, _1),
|
||||
bind(&HourMinutes::AddDuration, _val, _2))]
|
||||
;
|
||||
|
||||
extended_hour_minutes =
|
||||
(exthours >> lit(':') >> minutes)[bind(&HourMinutes::AddDuration, _val, _1),
|
||||
bind(&HourMinutes::AddDuration, _val, _2)]
|
||||
(exthours >> lit(':') >> minutes)[(bind(&HourMinutes::AddDuration, _val, _1),
|
||||
bind(&HourMinutes::AddDuration, _val, _2))]
|
||||
;
|
||||
|
||||
variable_time =
|
||||
|
@ -53,27 +53,27 @@ namespace osmoh
|
|||
|
||||
timespan =
|
||||
(time >> dash >> extended_time >> '/' >> hour_minutes)
|
||||
[bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2),
|
||||
bind(&Timespan::SetPeriod, _val, _3)]
|
||||
[(bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2),
|
||||
bind(&Timespan::SetPeriod, _val, _3))]
|
||||
|
||||
| (time >> dash >> extended_time >> '/' >> minutes)
|
||||
[bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2),
|
||||
bind(&Timespan::SetPeriod, _val, _3)]
|
||||
[(bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2),
|
||||
bind(&Timespan::SetPeriod, _val, _3))]
|
||||
|
||||
| (time >> dash >> extended_time >> '+')
|
||||
[bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2),
|
||||
bind(&Timespan::SetPlus, _val, true)]
|
||||
[(bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2),
|
||||
bind(&Timespan::SetPlus, _val, true))]
|
||||
|
||||
| (time >> dash >> extended_time)
|
||||
[bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2)]
|
||||
[(bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetEnd, _val, _2))]
|
||||
|
||||
| (time >> '+')
|
||||
[bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetPlus, _val, true)]
|
||||
[(bind(&Timespan::SetStart, _val, _1),
|
||||
bind(&Timespan::SetPlus, _val, true))]
|
||||
|
||||
// This rule is only used for collection_times tag wish is not in our interest.
|
||||
// | time[bind(&Timespan::SetStart, _val, _1)]
|
||||
|
|
|
@ -27,8 +27,8 @@ namespace osmoh
|
|||
| ushort_(4) [_val = NthWeekdayOfTheMonthEntry::NthDayOfTheMonth::Fourth]
|
||||
| ushort_(5) [_val = NthWeekdayOfTheMonthEntry::NthDayOfTheMonth::Fifth];
|
||||
|
||||
nth_entry = (nth >> dash >> nth) [bind(&NthWeekdayOfTheMonthEntry::SetStart, _val, _1),
|
||||
bind(&NthWeekdayOfTheMonthEntry::SetEnd, _val, _2)]
|
||||
nth_entry = (nth >> dash >> nth) [(bind(&NthWeekdayOfTheMonthEntry::SetStart, _val, _1),
|
||||
bind(&NthWeekdayOfTheMonthEntry::SetEnd, _val, _2))]
|
||||
| (lit('-') >> nth) [bind(&NthWeekdayOfTheMonthEntry::SetEnd, _val, _1)]
|
||||
| nth [bind(&NthWeekdayOfTheMonthEntry::SetStart, _val, _1)]
|
||||
;
|
||||
|
@ -50,8 +50,8 @@ namespace osmoh
|
|||
( charset::no_case[wdays] [bind(&WeekdayRange::SetStart, _val, _1)] >>
|
||||
'[' >> (nth_entry [bind(&WeekdayRange::AddNth, _val, _1)]) % ',') >> ']' >>
|
||||
-(day_offset [bind(&WeekdayRange::SetOffset, _val, _1)])
|
||||
| charset::no_case[(wdays >> dash >> wdays)] [bind(&WeekdayRange::SetStart, _val, _1),
|
||||
bind(&WeekdayRange::SetEnd, _val, _2)]
|
||||
| charset::no_case[(wdays >> dash >> wdays)] [(bind(&WeekdayRange::SetStart, _val, _1),
|
||||
bind(&WeekdayRange::SetEnd, _val, _2))]
|
||||
| charset::no_case[wdays] [bind(&WeekdayRange::SetStart, _val, _1)]
|
||||
;
|
||||
|
||||
|
@ -59,8 +59,8 @@ namespace osmoh
|
|||
;
|
||||
|
||||
main = (holiday_sequence >> -lit(',') >> weekday_sequence)
|
||||
[bind(&Weekdays::SetHolidays, _val, _1),
|
||||
bind(&Weekdays::SetWeekdayRanges, _val, _2)]
|
||||
[(bind(&Weekdays::SetHolidays, _val, _1),
|
||||
bind(&Weekdays::SetWeekdayRanges, _val, _2))]
|
||||
| holiday_sequence [bind(&Weekdays::SetHolidays, _val, _1)]
|
||||
| weekday_sequence [bind(&Weekdays::SetWeekdayRanges, _val, _1)]
|
||||
;
|
||||
|
|
|
@ -18,11 +18,11 @@ namespace osmoh
|
|||
using qi::_val;
|
||||
using osmoh::WeekRange;
|
||||
|
||||
week = (weeknum >> dash >> weeknum >> '/' >> uint_) [bind(&WeekRange::SetStart, _val, _1),
|
||||
bind(&WeekRange::SetEnd, _val, _2),
|
||||
bind(&WeekRange::SetPeriod, _val, _3)]
|
||||
| (weeknum >> dash >> weeknum) [bind(&WeekRange::SetStart, _val, _1),
|
||||
bind(&WeekRange::SetEnd, _val, _2)]
|
||||
week = (weeknum >> dash >> weeknum >> '/' >> uint_) [(bind(&WeekRange::SetStart, _val, _1),
|
||||
bind(&WeekRange::SetEnd, _val, _2),
|
||||
bind(&WeekRange::SetPeriod, _val, _3))]
|
||||
| (weeknum >> dash >> weeknum) [(bind(&WeekRange::SetStart, _val, _1),
|
||||
bind(&WeekRange::SetEnd, _val, _2))]
|
||||
| weeknum [bind(&WeekRange::SetStart, _val, _1)]
|
||||
;
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@ namespace osmoh
|
|||
|
||||
static const qi::int_parser<unsigned, 10, 4, 4> year = {};
|
||||
|
||||
year_range = (year >> dash >> year >> '/' >> uint_) [bind(&YearRange::SetStart, _val, _1),
|
||||
bind(&YearRange::SetEnd, _val, _2),
|
||||
bind(&YearRange::SetPeriod, _val, _3)]
|
||||
| (year >> dash >> year) [bind(&YearRange::SetStart, _val, _1),
|
||||
bind(&YearRange::SetEnd, _val, _2)]
|
||||
| (year >> lit('+')) [bind(&YearRange::SetStart, _val, _1),
|
||||
bind(&YearRange::SetPlus, _val, true)]
|
||||
year_range = (year >> dash >> year >> '/' >> uint_) [(bind(&YearRange::SetStart, _val, _1),
|
||||
bind(&YearRange::SetEnd, _val, _2),
|
||||
bind(&YearRange::SetPeriod, _val, _3))]
|
||||
| (year >> dash >> year) [(bind(&YearRange::SetStart, _val, _1),
|
||||
bind(&YearRange::SetEnd, _val, _2))]
|
||||
| (year >> lit('+')) [(bind(&YearRange::SetStart, _val, _1),
|
||||
bind(&YearRange::SetPlus, _val, true))]
|
||||
;
|
||||
|
||||
main %= (year_range % ',');
|
||||
|
|
1
3party/utf8cpp/include/utf8cpp
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../utfcpp/source
|
1
3party/utfcpp
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 6f0e7c7865208f2a6b882a7e138584beb1b6b2fd
|
|
@ -1,12 +0,0 @@
|
|||
utf8 cpp library
|
||||
Release 2.3.4
|
||||
|
||||
A minor bug fix release. Thanks to all who reported bugs.
|
||||
|
||||
Note: Version 2.3.3 contained a regression, and therefore was removed.
|
||||
|
||||
Changes from version 2.3.2
|
||||
- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
|
||||
- Bug fix [36]: replace_invalid() only works with back_inserter
|
||||
|
||||
Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include "utf8/checked.h"
|
||||
#include "utf8/unchecked.h"
|
||||
|
||||
#endif // header guard
|
|
@ -1,335 +0,0 @@
|
|||
// Copyright 2006-2016 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include "core.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
// Base for the exceptions that may be thrown from the library
|
||||
class exception : public ::std::exception {
|
||||
};
|
||||
|
||||
// Exceptions that may be thrown from the library functions.
|
||||
class invalid_code_point : public exception {
|
||||
uint32_t cp;
|
||||
public:
|
||||
invalid_code_point(uint32_t codepoint) : cp(codepoint) {}
|
||||
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid code point"; }
|
||||
uint32_t code_point() const {return cp;}
|
||||
};
|
||||
|
||||
class invalid_utf8 : public exception {
|
||||
uint8_t u8;
|
||||
public:
|
||||
invalid_utf8 (uint8_t u) : u8(u) {}
|
||||
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-8"; }
|
||||
uint8_t utf8_octet() const {return u8;}
|
||||
};
|
||||
|
||||
class invalid_utf16 : public exception {
|
||||
uint16_t u16;
|
||||
public:
|
||||
invalid_utf16 (uint16_t u) : u16(u) {}
|
||||
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-16"; }
|
||||
uint16_t utf16_word() const {return u16;}
|
||||
};
|
||||
|
||||
class not_enough_room : public exception {
|
||||
public:
|
||||
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Not enough space"; }
|
||||
};
|
||||
|
||||
/// The library API - functions intended to be called by the users
|
||||
|
||||
template <typename octet_iterator>
|
||||
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||
{
|
||||
if (!utf8::internal::is_code_point_valid(cp))
|
||||
throw invalid_code_point(cp);
|
||||
|
||||
if (cp < 0x80) // one octet
|
||||
*(result++) = static_cast<uint8_t>(cp);
|
||||
else if (cp < 0x800) { // two octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else if (cp < 0x10000) { // three octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else { // four octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename output_iterator>
|
||||
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
|
||||
{
|
||||
while (start != end) {
|
||||
octet_iterator sequence_start = start;
|
||||
internal::utf_error err_code = utf8::internal::validate_next(start, end);
|
||||
switch (err_code) {
|
||||
case internal::UTF8_OK :
|
||||
for (octet_iterator it = sequence_start; it != start; ++it)
|
||||
*out++ = *it;
|
||||
break;
|
||||
case internal::NOT_ENOUGH_ROOM:
|
||||
out = utf8::append (replacement, out);
|
||||
start = end;
|
||||
break;
|
||||
case internal::INVALID_LEAD:
|
||||
out = utf8::append (replacement, out);
|
||||
++start;
|
||||
break;
|
||||
case internal::INCOMPLETE_SEQUENCE:
|
||||
case internal::OVERLONG_SEQUENCE:
|
||||
case internal::INVALID_CODE_POINT:
|
||||
out = utf8::append (replacement, out);
|
||||
++start;
|
||||
// just one replacement mark for the sequence
|
||||
while (start != end && utf8::internal::is_trail(*start))
|
||||
++start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename output_iterator>
|
||||
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
|
||||
{
|
||||
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
|
||||
return utf8::replace_invalid(start, end, out, replacement_marker);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t next(octet_iterator& it, octet_iterator end)
|
||||
{
|
||||
uint32_t cp = 0;
|
||||
internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
|
||||
switch (err_code) {
|
||||
case internal::UTF8_OK :
|
||||
break;
|
||||
case internal::NOT_ENOUGH_ROOM :
|
||||
throw not_enough_room();
|
||||
case internal::INVALID_LEAD :
|
||||
case internal::INCOMPLETE_SEQUENCE :
|
||||
case internal::OVERLONG_SEQUENCE :
|
||||
throw invalid_utf8(*it);
|
||||
case internal::INVALID_CODE_POINT :
|
||||
throw invalid_code_point(cp);
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t peek_next(octet_iterator it, octet_iterator end)
|
||||
{
|
||||
return utf8::next(it, end);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t prior(octet_iterator& it, octet_iterator start)
|
||||
{
|
||||
// can't do much if it == start
|
||||
if (it == start)
|
||||
throw not_enough_room();
|
||||
|
||||
octet_iterator end = it;
|
||||
// Go back until we hit either a lead octet or start
|
||||
while (utf8::internal::is_trail(*(--it)))
|
||||
if (it == start)
|
||||
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||
return utf8::peek_next(it, end);
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename distance_type>
|
||||
void advance (octet_iterator& it, distance_type n, octet_iterator end)
|
||||
{
|
||||
const distance_type zero(0);
|
||||
if (n < zero) {
|
||||
// backward
|
||||
for (distance_type i = n; i < zero; ++i)
|
||||
utf8::prior(it, end);
|
||||
} else {
|
||||
// forward
|
||||
for (distance_type i = zero; i < n; ++i)
|
||||
utf8::next(it, end);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
typename std::iterator_traits<octet_iterator>::difference_type
|
||||
distance (octet_iterator first, octet_iterator last)
|
||||
{
|
||||
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||
for (dist = 0; first < last; ++dist)
|
||||
utf8::next(first, last);
|
||||
return dist;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end) {
|
||||
uint32_t cp = utf8::internal::mask16(*start++);
|
||||
// Take care of surrogate pairs first
|
||||
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||
if (start != end) {
|
||||
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||
if (utf8::internal::is_trail_surrogate(trail_surrogate))
|
||||
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||
else
|
||||
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
|
||||
}
|
||||
else
|
||||
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||
|
||||
}
|
||||
// Lone trail surrogate
|
||||
else if (utf8::internal::is_trail_surrogate(cp))
|
||||
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||
|
||||
result = utf8::append(cp, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||
{
|
||||
while (start < end) {
|
||||
uint32_t cp = utf8::next(start, end);
|
||||
if (cp > 0xffff) { //make a surrogate pair
|
||||
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||
}
|
||||
else
|
||||
*result++ = static_cast<uint16_t>(cp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end)
|
||||
result = utf8::append(*(start++), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||
{
|
||||
while (start < end)
|
||||
(*result++) = utf8::next(start, end);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// The iterator class
|
||||
template <typename octet_iterator>
|
||||
class iterator {
|
||||
octet_iterator it;
|
||||
octet_iterator range_start;
|
||||
octet_iterator range_end;
|
||||
public:
|
||||
typedef uint32_t value_type;
|
||||
typedef uint32_t* pointer;
|
||||
typedef uint32_t& reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
iterator () {}
|
||||
explicit iterator (const octet_iterator& octet_it,
|
||||
const octet_iterator& rangestart,
|
||||
const octet_iterator& rangeend) :
|
||||
it(octet_it), range_start(rangestart), range_end(rangeend)
|
||||
{
|
||||
if (it < range_start || it > range_end)
|
||||
throw std::out_of_range("Invalid utf-8 iterator position");
|
||||
}
|
||||
// the default "big three" are OK
|
||||
octet_iterator base () const { return it; }
|
||||
uint32_t operator * () const
|
||||
{
|
||||
octet_iterator temp = it;
|
||||
return utf8::next(temp, range_end);
|
||||
}
|
||||
bool operator == (const iterator& rhs) const
|
||||
{
|
||||
if (range_start != rhs.range_start || range_end != rhs.range_end)
|
||||
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
|
||||
return (it == rhs.it);
|
||||
}
|
||||
bool operator != (const iterator& rhs) const
|
||||
{
|
||||
return !(operator == (rhs));
|
||||
}
|
||||
iterator& operator ++ ()
|
||||
{
|
||||
utf8::next(it, range_end);
|
||||
return *this;
|
||||
}
|
||||
iterator operator ++ (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
utf8::next(it, range_end);
|
||||
return temp;
|
||||
}
|
||||
iterator& operator -- ()
|
||||
{
|
||||
utf8::prior(it, range_start);
|
||||
return *this;
|
||||
}
|
||||
iterator operator -- (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
utf8::prior(it, range_start);
|
||||
return temp;
|
||||
}
|
||||
}; // class iterator
|
||||
|
||||
} // namespace utf8
|
||||
|
||||
#if UTF_CPP_CPLUSPLUS >= 201703L // C++ 17 or later
|
||||
#include "cpp17.h"
|
||||
#elif UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
|
||||
#include "cpp11.h"
|
||||
#endif // C++ 11 or later
|
||||
|
||||
#endif //header guard
|
||||
|
|
@ -1,338 +0,0 @@
|
|||
// Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include <iterator>
|
||||
|
||||
// Determine the C++ standard version.
|
||||
// If the user defines UTF_CPP_CPLUSPLUS, use that.
|
||||
// Otherwise, trust the unreliable predefined macro __cplusplus
|
||||
|
||||
#if !defined UTF_CPP_CPLUSPLUS
|
||||
#define UTF_CPP_CPLUSPLUS __cplusplus
|
||||
#endif
|
||||
|
||||
#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
|
||||
#define UTF_CPP_OVERRIDE override
|
||||
#define UTF_CPP_NOEXCEPT noexcept
|
||||
#else // C++ 98/03
|
||||
#define UTF_CPP_OVERRIDE
|
||||
#define UTF_CPP_NOEXCEPT throw()
|
||||
#endif // C++ 11 or later
|
||||
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
|
||||
// You may need to change them to match your system.
|
||||
// These typedefs have the same names as ones from cstdint, or boost/cstdint
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
// Helper code - not intended to be directly called by the library users. May be changed at any time
|
||||
namespace internal
|
||||
{
|
||||
// Unicode constants
|
||||
// Leading (high) surrogates: 0xd800 - 0xdbff
|
||||
// Trailing (low) surrogates: 0xdc00 - 0xdfff
|
||||
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
|
||||
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
|
||||
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
|
||||
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
|
||||
const uint16_t LEAD_OFFSET = 0xd7c0u; // LEAD_SURROGATE_MIN - (0x10000 >> 10)
|
||||
const uint32_t SURROGATE_OFFSET = 0xfca02400u; // 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN
|
||||
|
||||
// Maximum valid value for a Unicode code point
|
||||
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
|
||||
|
||||
template<typename octet_type>
|
||||
inline uint8_t mask8(octet_type oc)
|
||||
{
|
||||
return static_cast<uint8_t>(0xff & oc);
|
||||
}
|
||||
template<typename u16_type>
|
||||
inline uint16_t mask16(u16_type oc)
|
||||
{
|
||||
return static_cast<uint16_t>(0xffff & oc);
|
||||
}
|
||||
template<typename octet_type>
|
||||
inline bool is_trail(octet_type oc)
|
||||
{
|
||||
return ((utf8::internal::mask8(oc) >> 6) == 0x2);
|
||||
}
|
||||
|
||||
template <typename u16>
|
||||
inline bool is_lead_surrogate(u16 cp)
|
||||
{
|
||||
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
|
||||
}
|
||||
|
||||
template <typename u16>
|
||||
inline bool is_trail_surrogate(u16 cp)
|
||||
{
|
||||
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||
}
|
||||
|
||||
template <typename u16>
|
||||
inline bool is_surrogate(u16 cp)
|
||||
{
|
||||
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||
}
|
||||
|
||||
template <typename u32>
|
||||
inline bool is_code_point_valid(u32 cp)
|
||||
{
|
||||
return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline typename std::iterator_traits<octet_iterator>::difference_type
|
||||
sequence_length(octet_iterator lead_it)
|
||||
{
|
||||
uint8_t lead = utf8::internal::mask8(*lead_it);
|
||||
if (lead < 0x80)
|
||||
return 1;
|
||||
else if ((lead >> 5) == 0x6)
|
||||
return 2;
|
||||
else if ((lead >> 4) == 0xe)
|
||||
return 3;
|
||||
else if ((lead >> 3) == 0x1e)
|
||||
return 4;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename octet_difference_type>
|
||||
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
|
||||
{
|
||||
if (cp < 0x80) {
|
||||
if (length != 1)
|
||||
return true;
|
||||
}
|
||||
else if (cp < 0x800) {
|
||||
if (length != 2)
|
||||
return true;
|
||||
}
|
||||
else if (cp < 0x10000) {
|
||||
if (length != 3)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
|
||||
|
||||
/// Helper for get_sequence_x
|
||||
template <typename octet_iterator>
|
||||
utf_error increase_safely(octet_iterator& it, octet_iterator end)
|
||||
{
|
||||
if (++it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
if (!utf8::internal::is_trail(*it))
|
||||
return INCOMPLETE_SEQUENCE;
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
|
||||
|
||||
/// get_sequence_x functions decode utf-8 sequences of the length x
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point += (*it) & 0x3f;
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
code_point = utf8::internal::mask8(*it);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||
|
||||
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||
|
||||
code_point += (*it) & 0x3f;
|
||||
|
||||
return UTF8_OK;
|
||||
}
|
||||
|
||||
#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
|
||||
|
||||
template <typename octet_iterator>
|
||||
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||
{
|
||||
if (it == end)
|
||||
return NOT_ENOUGH_ROOM;
|
||||
|
||||
// Save the original value of it so we can go back in case of failure
|
||||
// Of course, it does not make much sense with i.e. stream iterators
|
||||
octet_iterator original_it = it;
|
||||
|
||||
uint32_t cp = 0;
|
||||
// Determine the sequence length based on the lead octet
|
||||
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
|
||||
const octet_difference_type length = utf8::internal::sequence_length(it);
|
||||
|
||||
// Get trail octets and calculate the code point
|
||||
utf_error err = UTF8_OK;
|
||||
switch (length) {
|
||||
case 0:
|
||||
return INVALID_LEAD;
|
||||
case 1:
|
||||
err = utf8::internal::get_sequence_1(it, end, cp);
|
||||
break;
|
||||
case 2:
|
||||
err = utf8::internal::get_sequence_2(it, end, cp);
|
||||
break;
|
||||
case 3:
|
||||
err = utf8::internal::get_sequence_3(it, end, cp);
|
||||
break;
|
||||
case 4:
|
||||
err = utf8::internal::get_sequence_4(it, end, cp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err == UTF8_OK) {
|
||||
// Decoding succeeded. Now, security checks...
|
||||
if (utf8::internal::is_code_point_valid(cp)) {
|
||||
if (!utf8::internal::is_overlong_sequence(cp, length)){
|
||||
// Passed! Return here.
|
||||
code_point = cp;
|
||||
++it;
|
||||
return UTF8_OK;
|
||||
}
|
||||
else
|
||||
err = OVERLONG_SEQUENCE;
|
||||
}
|
||||
else
|
||||
err = INVALID_CODE_POINT;
|
||||
}
|
||||
|
||||
// Failure branch - restore the original value of the iterator
|
||||
it = original_it;
|
||||
return err;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
|
||||
uint32_t ignored;
|
||||
return utf8::internal::validate_next(it, end, ignored);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/// The library API - functions intended to be called by the users
|
||||
|
||||
// Byte order mark
|
||||
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
|
||||
|
||||
template <typename octet_iterator>
|
||||
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
|
||||
{
|
||||
octet_iterator result = start;
|
||||
while (result != end) {
|
||||
utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
|
||||
if (err_code != internal::UTF8_OK)
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline bool is_valid(octet_iterator start, octet_iterator end)
|
||||
{
|
||||
return (utf8::find_invalid(start, end) == end);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
|
||||
{
|
||||
return (
|
||||
((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
|
||||
((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
|
||||
((it != end) && (utf8::internal::mask8(*it)) == bom[2])
|
||||
);
|
||||
}
|
||||
} // namespace utf8
|
||||
|
||||
#endif // header guard
|
||||
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright 2018 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1
|
||||
#define UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1
|
||||
|
||||
#include "checked.h"
|
||||
#include <string>
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
|
||||
inline void append(char32_t cp, std::string& s)
|
||||
{
|
||||
append(uint32_t(cp), std::back_inserter(s));
|
||||
}
|
||||
|
||||
inline std::string utf16to8(const std::u16string& s)
|
||||
{
|
||||
std::string result;
|
||||
utf16to8(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::u16string utf8to16(const std::string& s)
|
||||
{
|
||||
std::u16string result;
|
||||
utf8to16(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string utf32to8(const std::u32string& s)
|
||||
{
|
||||
std::string result;
|
||||
utf32to8(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::u32string utf8to32(const std::string& s)
|
||||
{
|
||||
std::u32string result;
|
||||
utf8to32(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::size_t find_invalid(const std::string& s)
|
||||
{
|
||||
std::string::const_iterator invalid = find_invalid(s.begin(), s.end());
|
||||
return (invalid == s.end()) ? std::string::npos : (invalid - s.begin());
|
||||
}
|
||||
|
||||
inline bool is_valid(const std::string& s)
|
||||
{
|
||||
return is_valid(s.begin(), s.end());
|
||||
}
|
||||
|
||||
inline std::string replace_invalid(const std::string& s, char32_t replacement)
|
||||
{
|
||||
std::string result;
|
||||
replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string replace_invalid(const std::string& s)
|
||||
{
|
||||
std::string result;
|
||||
replace_invalid(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool starts_with_bom(const std::string& s)
|
||||
{
|
||||
return starts_with_bom(s.begin(), s.end());
|
||||
}
|
||||
|
||||
} // namespace utf8
|
||||
|
||||
#endif // header guard
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright 2018 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9
|
||||
#define UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9
|
||||
|
||||
#include "checked.h"
|
||||
#include <string>
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
|
||||
inline void append(char32_t cp, std::string& s)
|
||||
{
|
||||
append(uint32_t(cp), std::back_inserter(s));
|
||||
}
|
||||
|
||||
inline std::string utf16to8(std::u16string_view s)
|
||||
{
|
||||
std::string result;
|
||||
utf16to8(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::u16string utf8to16(std::string_view s)
|
||||
{
|
||||
std::u16string result;
|
||||
utf8to16(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string utf32to8(std::u32string_view s)
|
||||
{
|
||||
std::string result;
|
||||
utf32to8(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::u32string utf8to32(std::string_view s)
|
||||
{
|
||||
std::u32string result;
|
||||
utf8to32(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::size_t find_invalid(std::string_view s)
|
||||
{
|
||||
std::string_view::const_iterator invalid = find_invalid(s.begin(), s.end());
|
||||
return (invalid == s.end()) ? std::string_view::npos : (invalid - s.begin());
|
||||
}
|
||||
|
||||
inline bool is_valid(std::string_view s)
|
||||
{
|
||||
return is_valid(s.begin(), s.end());
|
||||
}
|
||||
|
||||
inline std::string replace_invalid(std::string_view s, char32_t replacement)
|
||||
{
|
||||
std::string result;
|
||||
replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string replace_invalid(std::string_view s)
|
||||
{
|
||||
std::string result;
|
||||
replace_invalid(s.begin(), s.end(), std::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool starts_with_bom(std::string_view s)
|
||||
{
|
||||
return starts_with_bom(s.begin(), s.end());
|
||||
}
|
||||
|
||||
} // namespace utf8
|
||||
|
||||
#endif // header guard
|
||||
|
|
@ -1,274 +0,0 @@
|
|||
// Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include "core.h"
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
namespace unchecked
|
||||
{
|
||||
template <typename octet_iterator>
|
||||
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||
{
|
||||
if (cp < 0x80) // one octet
|
||||
*(result++) = static_cast<uint8_t>(cp);
|
||||
else if (cp < 0x800) { // two octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else if (cp < 0x10000) { // three octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
else { // four octets
|
||||
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
|
||||
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename output_iterator>
|
||||
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
|
||||
{
|
||||
while (start != end) {
|
||||
octet_iterator sequence_start = start;
|
||||
internal::utf_error err_code = utf8::internal::validate_next(start, end);
|
||||
switch (err_code) {
|
||||
case internal::UTF8_OK :
|
||||
for (octet_iterator it = sequence_start; it != start; ++it)
|
||||
*out++ = *it;
|
||||
break;
|
||||
case internal::NOT_ENOUGH_ROOM:
|
||||
out = utf8::unchecked::append (replacement, out);
|
||||
start = end;
|
||||
break;
|
||||
case internal::INVALID_LEAD:
|
||||
out = utf8::unchecked::append (replacement, out);
|
||||
++start;
|
||||
break;
|
||||
case internal::INCOMPLETE_SEQUENCE:
|
||||
case internal::OVERLONG_SEQUENCE:
|
||||
case internal::INVALID_CODE_POINT:
|
||||
out = utf8::unchecked::append (replacement, out);
|
||||
++start;
|
||||
// just one replacement mark for the sequence
|
||||
while (start != end && utf8::internal::is_trail(*start))
|
||||
++start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename output_iterator>
|
||||
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
|
||||
{
|
||||
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
|
||||
return utf8::unchecked::replace_invalid(start, end, out, replacement_marker);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t next(octet_iterator& it)
|
||||
{
|
||||
uint32_t cp = utf8::internal::mask8(*it);
|
||||
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
|
||||
switch (length) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
it++;
|
||||
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||
break;
|
||||
case 3:
|
||||
++it;
|
||||
cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||
++it;
|
||||
cp += (*it) & 0x3f;
|
||||
break;
|
||||
case 4:
|
||||
++it;
|
||||
cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||
++it;
|
||||
cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||
++it;
|
||||
cp += (*it) & 0x3f;
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
return cp;
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t peek_next(octet_iterator it)
|
||||
{
|
||||
return utf8::unchecked::next(it);
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
uint32_t prior(octet_iterator& it)
|
||||
{
|
||||
while (utf8::internal::is_trail(*(--it))) ;
|
||||
octet_iterator temp = it;
|
||||
return utf8::unchecked::next(temp);
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename distance_type>
|
||||
void advance (octet_iterator& it, distance_type n)
|
||||
{
|
||||
const distance_type zero(0);
|
||||
if (n < zero) {
|
||||
// backward
|
||||
for (distance_type i = n; i < zero; ++i)
|
||||
utf8::unchecked::prior(it);
|
||||
} else {
|
||||
// forward
|
||||
for (distance_type i = zero; i < n; ++i)
|
||||
utf8::unchecked::next(it);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename octet_iterator>
|
||||
typename std::iterator_traits<octet_iterator>::difference_type
|
||||
distance (octet_iterator first, octet_iterator last)
|
||||
{
|
||||
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||
for (dist = 0; first < last; ++dist)
|
||||
utf8::unchecked::next(first);
|
||||
return dist;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end) {
|
||||
uint32_t cp = utf8::internal::mask16(*start++);
|
||||
// Take care of surrogate pairs first
|
||||
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||
}
|
||||
result = utf8::unchecked::append(cp, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename u16bit_iterator, typename octet_iterator>
|
||||
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||
{
|
||||
while (start < end) {
|
||||
uint32_t cp = utf8::unchecked::next(start);
|
||||
if (cp > 0xffff) { //make a surrogate pair
|
||||
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||
}
|
||||
else
|
||||
*result++ = static_cast<uint16_t>(cp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||
{
|
||||
while (start != end)
|
||||
result = utf8::unchecked::append(*(start++), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename octet_iterator, typename u32bit_iterator>
|
||||
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||
{
|
||||
while (start < end)
|
||||
(*result++) = utf8::unchecked::next(start);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// The iterator class
|
||||
template <typename octet_iterator>
|
||||
class iterator {
|
||||
octet_iterator it;
|
||||
public:
|
||||
typedef uint32_t value_type;
|
||||
typedef uint32_t* pointer;
|
||||
typedef uint32_t& reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
iterator () {}
|
||||
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
|
||||
// the default "big three" are OK
|
||||
octet_iterator base () const { return it; }
|
||||
uint32_t operator * () const
|
||||
{
|
||||
octet_iterator temp = it;
|
||||
return utf8::unchecked::next(temp);
|
||||
}
|
||||
bool operator == (const iterator& rhs) const
|
||||
{
|
||||
return (it == rhs.it);
|
||||
}
|
||||
bool operator != (const iterator& rhs) const
|
||||
{
|
||||
return !(operator == (rhs));
|
||||
}
|
||||
iterator& operator ++ ()
|
||||
{
|
||||
::std::advance(it, utf8::internal::sequence_length(it));
|
||||
return *this;
|
||||
}
|
||||
iterator operator ++ (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
::std::advance(it, utf8::internal::sequence_length(it));
|
||||
return temp;
|
||||
}
|
||||
iterator& operator -- ()
|
||||
{
|
||||
utf8::unchecked::prior(it);
|
||||
return *this;
|
||||
}
|
||||
iterator operator -- (int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
utf8::unchecked::prior(it);
|
||||
return temp;
|
||||
}
|
||||
}; // class iterator
|
||||
|
||||
} // namespace utf8::unchecked
|
||||
} // namespace utf8
|
||||
|
||||
|
||||
#endif // header guard
|
||||
|
|
@ -7,7 +7,16 @@ set(SRC
|
|||
|
||||
add_library(${PROJECT_NAME} ${SRC})
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC . ../Vulkan-Headers/include)
|
||||
if (WITH_SYSTEM_PROVIDED_3PARTY)
|
||||
find_package(VulkanHeaders REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} Vulkan::Headers)
|
||||
else()
|
||||
set(VulkanHeaders_INCLUDE_DIR ../Vulkan-Headers/include)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ../Vulkan-Headers/include)
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC .)
|
||||
|
||||
|
||||
# dlopen
|
||||
target_link_libraries(${PROJECT_NAME} $<$<BOOL:CMAKE_DL_LIBS>:${CMAKE_DL_LIBS}>)
|
||||
|
|
|
@ -961,8 +961,10 @@ PFN_vkDestroyPrivateDataSlotEXT vkDestroyPrivateDataSlotEXT;
|
|||
PFN_vkSetPrivateDataEXT vkSetPrivateDataEXT;
|
||||
PFN_vkGetPrivateDataEXT vkGetPrivateDataEXT;
|
||||
PFN_vkCmdSetFragmentShadingRateEnumNV vkCmdSetFragmentShadingRateEnumNV;
|
||||
PFN_vkAcquireWinrtDisplayNV vkAcquireWinrtDisplayNV;
|
||||
PFN_vkGetWinrtDisplayNV vkGetWinrtDisplayNV;
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
PFN_vkAcquireWinrtDisplayNV vkAcquireWinrtDisplayNV;
|
||||
PFN_vkGetWinrtDisplayNV vkGetWinrtDisplayNV;
|
||||
#endif
|
||||
PFN_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT;
|
||||
PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
|
||||
PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
|
||||
|
|
|
@ -22,6 +22,8 @@ endif()
|
|||
|
||||
message(STATUS "Using compiler ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
|
||||
option(COVERAGE_REPORT "Configure for coverage report" OFF)
|
||||
|
||||
option(UNITY_DISABLE "Disable unity build" OFF)
|
||||
if (NOT UNITY_DISABLE AND NOT DEFINED ENV{UNITY_DISABLE})
|
||||
set(CMAKE_UNITY_BUILD ON)
|
||||
|
@ -58,6 +60,7 @@ set(OMIM_ROOT ${CMAKE_SOURCE_DIR})
|
|||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${OMIM_ROOT}/cmake")
|
||||
|
||||
include(OmimHelpers)
|
||||
include(OmimTesting)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(LINUX_DETECTED TRUE)
|
||||
|
@ -131,7 +134,7 @@ option(USE_ASAN "Enable Address Sanitizer" OFF)
|
|||
option(USE_TSAN "Enable Thread Sanitizer" OFF)
|
||||
option(USE_LIBFUZZER "Enable LibFuzzer" OFF)
|
||||
option(PYBINDINGS "Create makefiles for building python bindings" OFF)
|
||||
option(SKIP_DESKTOP "Skip building of desktop application" OFF)
|
||||
option(SKIP_QT_GUI "Skip building of Qt GUI" OFF)
|
||||
# TODO: Fix mapshot, it doesn't work without our old FreeType hack.
|
||||
option(BUILD_MAPSHOT "Build mapshot tool" OFF)
|
||||
option(USE_PCH "Use precompiled headers" OFF)
|
||||
|
@ -208,7 +211,12 @@ if (PLATFORM_LINUX OR PLATFORM_ANDROID)
|
|||
endif()
|
||||
|
||||
if (NOT SKIP_TESTS)
|
||||
set(SKIP_TESTS FALSE)
|
||||
enable_testing()
|
||||
# Enables ctest -T memcheck with valgrind
|
||||
include(CTest)
|
||||
if (COVERAGE_REPORT)
|
||||
include(OmimCoverage)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (NOT PYTHON_VERSION)
|
||||
|
@ -234,22 +242,14 @@ endif()
|
|||
|
||||
if (NOT PLATFORM_IPHONE AND NOT PLATFORM_ANDROID)
|
||||
list(APPEND qt_components Core Network)
|
||||
if (NOT SKIP_DESKTOP OR NOT SKIP_TESTS OR PYBINDINGS)
|
||||
if (NOT SKIP_QT_GUI OR NOT SKIP_TESTS OR PYBINDINGS)
|
||||
list(APPEND qt_components Widgets)
|
||||
endif()
|
||||
if (NOT SKIP_DESKTOP)
|
||||
list(APPEND qt_components Gui Xml Svg)
|
||||
endif()
|
||||
if (DEFINED ENV{HOMEBREW_PREFIX})
|
||||
set(HOMEBREW_PREFIX $ENV{HOMEBREW_PREFIX})
|
||||
else()
|
||||
set(HOMEBREW_PREFIX /opt/homebrew)
|
||||
endif()
|
||||
# PATHS are hard-coded hints where to look for qt5 in addition to other places.
|
||||
find_package(Qt5 COMPONENTS REQUIRED ${qt_components} PATHS $ENV{QT_PATH} ${HOMEBREW_PREFIX}/opt/qt@5 /usr/local/opt/qt@5 /usr/lib/x86_64-linux-gnu/qt5)
|
||||
if (Qt5_VERSION VERSION_LESS 5.5.0)
|
||||
message(FATAL_ERROR "Minimum supported Qt5 version is 5.5")
|
||||
if (NOT SKIP_QT_GUI)
|
||||
list(APPEND qt_components Gui Xml Svg OpenGL OpenGLWidgets)
|
||||
endif()
|
||||
# PATHS are hard-coded hints where to look for qt6 in addition to other places.
|
||||
find_package(Qt6 COMPONENTS REQUIRED ${qt_components} PATHS $ENV{QT_PATH} /opt/homebrew/opt/qt@6 /usr/local/opt/qt@6 /usr/lib/x86_64-linux-gnu/qt6)
|
||||
endif()
|
||||
|
||||
find_library(LIBZ NAMES z)
|
||||
|
@ -290,68 +290,21 @@ if (USE_PCH)
|
|||
${OMIM_PCH_TARGET_NAME}
|
||||
)
|
||||
endif()
|
||||
# Include 3party dependencies.
|
||||
|
||||
if (NOT WITH_SYSTEM_PROVIDED_3PARTY)
|
||||
# Configure expat library.
|
||||
# Suppress "Policy CMP0077 is not set: option() honors normal variables"
|
||||
# for the expat options below.
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
||||
set(EXPAT_BUILD_TOOLS OFF)
|
||||
set(EXPAT_BUILD_EXAMPLES OFF)
|
||||
set(EXPAT_BUILD_TESTS OFF)
|
||||
set(EXPAT_BUILD_DOCS OFF)
|
||||
set(EXPAT_BUILD_PKGCONFIG OFF)
|
||||
set(EXPAT_ENABLE_INSTALL OFF)
|
||||
set(EXPAT_SHARED_LIBS OFF)
|
||||
add_subdirectory(3party/expat/expat)
|
||||
|
||||
# Configure Jansson library.
|
||||
set(JANSSON_BUILD_DOCS OFF)
|
||||
set(JANSSON_BUILD_MAN OFF)
|
||||
set(JANSSON_EXAMPLES OFF)
|
||||
set(JANSSON_INSTALL OFF)
|
||||
set(JANSSON_WITHOUT_TESTS ON)
|
||||
add_subdirectory(3party/jansson/jansson/)
|
||||
target_include_directories(jansson INTERFACE "${PROJECT_BINARY_DIR}/3party/jansson/jansson/include")
|
||||
|
||||
# Add pugixml library.
|
||||
add_subdirectory(3party/pugixml)
|
||||
|
||||
# Add protobuf library.
|
||||
add_subdirectory(${OMIM_ROOT}/3party/protobuf)
|
||||
endif()
|
||||
|
||||
add_subdirectory(3party/agg)
|
||||
add_subdirectory(3party/bsdiff-courgette)
|
||||
|
||||
add_subdirectory(3party/gflags)
|
||||
target_compile_options(gflags_nothreads_static PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wno-subobject-linkage>)
|
||||
# Not needed for the usual build process, but it fixes QtCreator editor,
|
||||
# that doesn't see gflags/gflags.h in binary dir (gflags has tricky cmake configuration).
|
||||
if (PLATFORM_DESKTOP)
|
||||
include_directories("${PROJECT_BINARY_DIR}/3party/gflags/include")
|
||||
endif()
|
||||
|
||||
# Should be on the root level, not in 3party, so tests can get these dependencies.
|
||||
# Should go before 3party as harfbuzz is using them.
|
||||
if (LINUX_DETECTED)
|
||||
find_package(ICU COMPONENTS uc i18n data REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
else()
|
||||
add_subdirectory(3party/freetype)
|
||||
add_subdirectory(3party/icu)
|
||||
endif()
|
||||
|
||||
add_subdirectory(3party/liboauthcpp)
|
||||
add_subdirectory(3party/minizip)
|
||||
add_subdirectory(3party/opening_hours)
|
||||
add_subdirectory(3party/sdf_image)
|
||||
add_subdirectory(3party/stb_image)
|
||||
add_subdirectory(3party/succinct)
|
||||
add_subdirectory(3party/open-location-code)
|
||||
add_subdirectory(3party/vulkan_wrapper)
|
||||
# Include 3party dependencies.
|
||||
add_subdirectory(3party)
|
||||
|
||||
if (PLATFORM_DESKTOP)
|
||||
add_subdirectory(3party/libtess2)
|
||||
# Not needed for the usual build process, but it fixes QtCreator editor,
|
||||
# that doesn't see gflags/gflags.h in binary dir (gflags has tricky cmake configuration).
|
||||
if (PLATFORM_DESKTOP AND NOT WITH_SYSTEM_PROVIDED_3PARTY)
|
||||
include_directories("${PROJECT_BINARY_DIR}/3party/gflags/include")
|
||||
endif()
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
|
@ -396,7 +349,7 @@ if (PLATFORM_DESKTOP)
|
|||
omim_add_tool_subdirectory(topography_generator)
|
||||
add_subdirectory(track_analyzing)
|
||||
omim_add_tool_subdirectory(track_generator)
|
||||
if (NOT SKIP_DESKTOP)
|
||||
if (NOT SKIP_QT_GUI)
|
||||
add_subdirectory(qt)
|
||||
omim_add_tool_subdirectory(skin_generator)
|
||||
endif()
|
||||
|
@ -405,5 +358,5 @@ endif()
|
|||
omim_add_test_subdirectory(qt_tstfrm)
|
||||
|
||||
if (PLATFORM_ANDROID)
|
||||
add_subdirectory(android/jni)
|
||||
add_subdirectory(android/app/src/main/cpp)
|
||||
endif()
|
||||
|
|
1
CONTRIBUTING.md
Normal file
|
@ -0,0 +1 @@
|
|||
See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md)
|
|
@ -38,6 +38,7 @@ Code contributions:
|
|||
Roman Tsisyk <roman@tsisyk.com>
|
||||
Caspar Nuël <casparnuel@yandex.com>
|
||||
Konstantin Pastbin
|
||||
Nishant Bhandari <nishantbhandari0019@gmail.com>
|
||||
|
||||
Porting to Tizen platform:
|
||||
Sergey Pisarchik
|
||||
|
|
1
INSTALL.md
Normal file
|
@ -0,0 +1 @@
|
|||
See [docs/INSTALL.md](docs/INSTALL.md)
|
55
README.md
|
@ -2,25 +2,25 @@
|
|||
|
||||
<a name="install"/>
|
||||
|
||||
[Organic Maps](https://organicmaps.app) is a free Android & iOS offline maps app for travelers, tourists, drivers, hikers, and cyclists.
|
||||
It uses crowd-sourced [OpenStreetMap](https://www.openstreetmap.org) data and is developed with love by creators of **MapsWithMe** app (later renamed to **Maps.Me**) and by our community.
|
||||
[Organic Maps](https://organicmaps.app) is a free Android & iOS offline maps app for travellers, tourists, drivers, hikers, and cyclists.
|
||||
It uses crowd-sourced [OpenStreetMap](https://www.openstreetmap.org) data and is developed with love by the creators of **MapsWithMe** (later renamed to **Maps.Me**) and by our community.
|
||||
No ads, no tracking, no data collection, no crapware. Your [donations](https://organicmaps.app/donate/) and positive reviews motivate and inspire us, thanks ❤️!
|
||||
|
||||
<p float="left">
|
||||
<a href="https://apps.apple.com/app/organic-maps/id1567437057">
|
||||
<img src="docs/badges/apple-appstore.png" width="180">
|
||||
<img alt="Download on the App Store" src="docs/badges/apple-appstore.png" width="180">
|
||||
</a>
|
||||
<a href="https://play.google.com/store/apps/details?id=app.organicmaps">
|
||||
<img src="docs/badges/google-play.png" width="180">
|
||||
<img alt="Get it on Google Play" src="docs/badges/google-play.png" width="180">
|
||||
</a>
|
||||
<a href="https://appgallery.huawei.com/#/app/C104325611">
|
||||
<img src="docs/badges/huawei-appgallery.png" width="180">
|
||||
<img alt="Explore it on AppGallery" src="docs/badges/huawei-appgallery.png" width="180">
|
||||
</a>
|
||||
<a href="https://f-droid.org/en/packages/app.organicmaps/">
|
||||
<img src="docs/badges/fdroid.png" width="180">
|
||||
<img alt="Get it on F-Droid" src="docs/badges/fdroid.png" width="180">
|
||||
</a>
|
||||
<a href='https://flathub.org/apps/details/app.organicmaps.desktop'>
|
||||
<img alt="Download on Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.png" width="180"/>
|
||||
<img alt="Download on Flathub" src="docs/badges/flathub.png" width="180"/>
|
||||
</a>
|
||||
<a href="https://repology.org/project/organicmaps/versions">
|
||||
<img src="https://repology.org/badge/vertical-allrepos/organicmaps.svg" width="180" alt="Packaging status">
|
||||
|
@ -28,22 +28,22 @@ No ads, no tracking, no data collection, no crapware. Your [donations](https://o
|
|||
</p>
|
||||
|
||||
<p float="left">
|
||||
<img src="android/src/fdroid/play/listings/en-US/graphics/phone-screenshots/1.jpg" width="400" />
|
||||
<img src="android/src/fdroid/play/listings/en-US/graphics/phone-screenshots/2.jpg" width="400" />
|
||||
<img src="android/src/fdroid/play/listings/en-US/graphics/phone-screenshots/3.jpg" width="400" />
|
||||
<img src="android/src/fdroid/play/listings/en-US/graphics/phone-screenshots/4.jpg" width="400" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/1.jpg" width="400" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/2.jpg" width="400" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/3.jpg" width="400" />
|
||||
<img src="android/app/src/fdroid/play/listings/en-US/graphics/phone-screenshots/4.jpg" width="400" />
|
||||
</p>
|
||||
|
||||
## Features
|
||||
|
||||
Organic Maps is the ultimate companion app for travelers, tourists, hikers, and cyclists:
|
||||
Organic Maps is the ultimate companion app for travellers, tourists, hikers, and cyclists:
|
||||
|
||||
- Detailed offline maps with places that don't exist on other maps, thanks to [OpenStreetMap](https://osm.org)
|
||||
- Detailed offline maps with places that don't exist on other maps, thanks to [OpenStreetMap](https://openstreetmap.org)
|
||||
- Cycling routes, hiking trails, and walking paths
|
||||
- Contour lines, elevation profiles, peaks, and slopes
|
||||
- Turn-by-turn walking, cycling, and car navigation with voice guidance
|
||||
- Fast offline search on the map
|
||||
- Bookmarks export and import in KML/KMZ formats (GPX is [planned](https://github.com/organicmaps/organicmaps/issues/624))
|
||||
- Bookmarks and tracks import and export in KML, KMZ & GPX formats
|
||||
- Dark Mode to protect your eyes
|
||||
- Countries and regions don't take a lot of space
|
||||
- Free and open-source
|
||||
|
@ -56,7 +56,7 @@ Organic Maps is pure and organic, made with love:
|
|||
- Saves your battery
|
||||
- No unexpected mobile data charges
|
||||
|
||||
Organic Maps app is free from trackers and other bad stuff:
|
||||
Organic Maps is free from trackers and other bad stuff:
|
||||
|
||||
- No ads
|
||||
- No tracking
|
||||
|
@ -69,11 +69,16 @@ Organic Maps app is free from trackers and other bad stuff:
|
|||
- No crapware
|
||||
- ~~No pesticides~~ Purely organic!
|
||||
|
||||
The application is verified by <a href="https://reports.exodus-privacy.eu.org/en/reports/app.organicmaps/latest/">Exodus Privacy Project:
|
||||
The Android application is verified by the <a href="https://reports.exodus-privacy.eu.org/en/reports/app.organicmaps/latest/">Exodus Privacy Project:
|
||||
|
||||
<img src="docs/privacy/exodus.png" width="400">
|
||||
</a>
|
||||
|
||||
The iOS application is verified by <a href="https://ios.trackercontrol.org/analysis/app.organicmaps">TrackerControl for iOS:
|
||||
|
||||
<img src="docs/privacy/trackercontrol-ios.png" width="400">
|
||||
</a>
|
||||
|
||||
<br/>
|
||||
|
||||
Organic Maps doesn't request excessive permissions to spy on you:
|
||||
|
@ -87,20 +92,20 @@ At Organic Maps, we believe that privacy is a fundamental human right:
|
|||
|
||||
- Organic Maps is an indie community-driven open-source project
|
||||
- We protect your privacy from Big Tech's prying eyes
|
||||
- Stay safe no matter wherever you are
|
||||
- Stay safe no matter where you are
|
||||
|
||||
Reject surveillance - embrace your freedom.
|
||||
|
||||
[**Give Organic Maps a try!**](#install)
|
||||
|
||||
## Who is paying for the free app?
|
||||
## Who is paying for the development?
|
||||
|
||||
The app is free for everyone. Please [donate](https://organicmaps.app/donate) to support us!
|
||||
The app is free for everyone, so we rely on donations. Please donate at [organicmaps.app/donate](https://organicmaps.app/donate) to support us!
|
||||
|
||||
### Our sponsors
|
||||
|
||||
[Mythic Beasts](https://www.mythic-beasts.com/) ISP [provides us](https://www.mythic-beasts.com/blog/2021/10/06/improving-the-world-bit-by-expensive-bit/)
|
||||
two virtual servers with 400 TB/month of free bandwidth to help our users with
|
||||
two virtual servers with 400 TB/month of free bandwidth to host and serve
|
||||
maps downloads and updates.
|
||||
|
||||
## Copyrights
|
||||
|
@ -109,27 +114,27 @@ Licensed under the Apache License, Version 2.0. See
|
|||
[LICENSE](https://github.com/organicmaps/organicmaps/blob/master/LICENSE),
|
||||
[NOTICE](https://github.com/organicmaps/organicmaps/blob/master/NOTICE)
|
||||
and [data/copyright.html](http://htmlpreview.github.io/?https://github.com/organicmaps/organicmaps/blob/master/data/copyright.html)
|
||||
files for more information.
|
||||
for more information.
|
||||
|
||||
## Governance
|
||||
|
||||
See [GOVERNANCE](docs/GOVERNANCE.md).
|
||||
See [docs/GOVERNANCE.md)](docs/GOVERNANCE.md).
|
||||
|
||||
## Contributing
|
||||
|
||||
If you want to build the project, check [docs/INSTALL.md](docs/INSTALL.md). If you want to help the project,
|
||||
see [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) and read everything in the [docs folder](docs/) of the repository.
|
||||
see [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md). You can [help in many ways](https://organicmaps.app/support-us/), the ability to code is not necessary.
|
||||
|
||||
## Beta
|
||||
|
||||
Please join our beta program, suggest your features, and report bugs:
|
||||
|
||||
- [iOS Beta (TestFlight)](https://testflight.apple.com/join/lrKCl08I)
|
||||
- [Android Beta (Firebase)](https://appdistribution.firebase.dev/i/9ec3bca5e2b47373)
|
||||
- [Android Beta (Firebase)](https://appdistribution.firebase.dev/i/2f0fee463107b137)
|
||||
|
||||
## Feedback
|
||||
|
||||
- **Rate us on [App Store](https://apps.apple.com/app/organic-maps/id1567437057)
|
||||
- **Rate us on the [App Store](https://apps.apple.com/app/organic-maps/id1567437057)
|
||||
and [Google Play](https://play.google.com/store/apps/details?id=app.organicmaps)**.
|
||||
- **Star us on GitHub**.
|
||||
- Report bugs or issues to [the issue tracker](https://github.com/organicmaps/organicmaps/issues).
|
||||
|
|
47
android/.gitignore
vendored
|
@ -1,40 +1,23 @@
|
|||
bin
|
||||
gen
|
||||
/libs/
|
||||
.settings
|
||||
resbuilder
|
||||
spoon-output
|
||||
obj
|
||||
local
|
||||
.gradle
|
||||
build
|
||||
3rd_party/api-android/
|
||||
RELEASE
|
||||
.idea
|
||||
.externalNativeBuild
|
||||
nativeOutputs
|
||||
|
||||
# For now, ignore Android Studio projects
|
||||
# default android studio ignore list
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
|
||||
*.class
|
||||
.classpath
|
||||
.cproject
|
||||
.project
|
||||
local.properties
|
||||
lint.xml
|
||||
.gradletasknamecache
|
||||
|
||||
# ignore flags symlinks
|
||||
res/drawable-xhdpi/??.png
|
||||
res/drawable-xhdpi/do_hack.png
|
||||
res/drawable-xhdpi/uk_england.png
|
||||
res/drawable-xhdpi/uk_northern_ireland.png
|
||||
res/drawable-xhdpi/uk_scotland.png
|
||||
res/drawable-xhdpi/uk_wales.png
|
||||
res/drawable-mdpi/??.png
|
||||
res/drawable-mdpi/do_hack.png
|
||||
res/drawable-mdpi/uk_england.png
|
||||
res/drawable-mdpi/uk_northern_ireland.png
|
||||
res/drawable-mdpi/uk_scotland.png
|
||||
res/drawable-mdpi/uk_wales.png
|
||||
|
|
|
@ -1,752 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:installLocation="auto">
|
||||
|
||||
<uses-feature
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true"/>
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="true"/>
|
||||
<uses-feature
|
||||
android:name="android.hardware.wifi"
|
||||
android:required="false"/>
|
||||
<uses-feature
|
||||
android:name="android.hardware.location"
|
||||
android:required="false"/>
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.network"
|
||||
android:required="false"/>
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
android:required="false"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<!--
|
||||
https://developer.android.com/reference/androidx/core/app/JobIntentService:
|
||||
When running on Android O, the JobScheduler will take care of wake locks
|
||||
for you (holding a wake lock from the time you enqueue work until the job
|
||||
has been dispatched and while it is running). When running on previous
|
||||
versions of the platform, this wake lock handling is emulated in the
|
||||
class here by directly calling the PowerManager; this means
|
||||
the application must request the Manifest.permission.WAKE_LOCK permission.
|
||||
//-->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<!--
|
||||
Android 13 (API level 33) and higher supports a runtime permission for sending non-exempt (including Foreground
|
||||
Services (FGS)) notifications from an app.
|
||||
//-->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.TTS_SERVICE"/>
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<!-- -->
|
||||
<supports-screens
|
||||
android:largeScreens="true"
|
||||
android:xlargeScreens="true"/>
|
||||
|
||||
<application
|
||||
android:name=".MwmApplication"
|
||||
android:allowBackup="true"
|
||||
android:backupInForeground="true"
|
||||
android:fullBackupContent="@xml/backup_content"
|
||||
android:dataExtractionRules="@xml/backup_content_v31"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:localeConfig="@xml/locales_config"
|
||||
android:theme="@style/MwmTheme"
|
||||
android:supportsRtl="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
tools:targetApi="t">
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.SplashActivity"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="geo"/>
|
||||
<data android:scheme="ge0"/>
|
||||
<data android:scheme="om"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:host="ge0.me"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="@bool/autoVerify">
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:host="omaps.app"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:pathPrefix="/maps"/>
|
||||
<!-- Generated from https://www.google.com/supported_domains //-->
|
||||
<data android:host="maps.google.ad"/>
|
||||
<data android:host="maps.google.ae"/>
|
||||
<data android:host="maps.google.al"/>
|
||||
<data android:host="maps.google.am"/>
|
||||
<data android:host="maps.google.as"/>
|
||||
<data android:host="maps.google.at"/>
|
||||
<data android:host="maps.google.az"/>
|
||||
<data android:host="maps.google.ba"/>
|
||||
<data android:host="maps.google.be"/>
|
||||
<data android:host="maps.google.bf"/>
|
||||
<data android:host="maps.google.bg"/>
|
||||
<data android:host="maps.google.bi"/>
|
||||
<data android:host="maps.google.bj"/>
|
||||
<data android:host="maps.google.bs"/>
|
||||
<data android:host="maps.google.bt"/>
|
||||
<data android:host="maps.google.by"/>
|
||||
<data android:host="maps.google.ca"/>
|
||||
<data android:host="maps.google.cat"/>
|
||||
<data android:host="maps.google.cd"/>
|
||||
<data android:host="maps.google.cf"/>
|
||||
<data android:host="maps.google.cg"/>
|
||||
<data android:host="maps.google.ch"/>
|
||||
<data android:host="maps.google.ci"/>
|
||||
<data android:host="maps.google.cl"/>
|
||||
<data android:host="maps.google.cm"/>
|
||||
<data android:host="maps.google.cn"/>
|
||||
<data android:host="maps.google.co.ao"/>
|
||||
<data android:host="maps.google.co.bw"/>
|
||||
<data android:host="maps.google.co.ck"/>
|
||||
<data android:host="maps.google.co.cr"/>
|
||||
<data android:host="maps.google.co.id"/>
|
||||
<data android:host="maps.google.co.il"/>
|
||||
<data android:host="maps.google.co.in"/>
|
||||
<data android:host="maps.google.co.jp"/>
|
||||
<data android:host="maps.google.co.ke"/>
|
||||
<data android:host="maps.google.co.kr"/>
|
||||
<data android:host="maps.google.co.ls"/>
|
||||
<data android:host="maps.google.co.ma"/>
|
||||
<data android:host="maps.google.co.mz"/>
|
||||
<data android:host="maps.google.co.nz"/>
|
||||
<data android:host="maps.google.co.th"/>
|
||||
<data android:host="maps.google.co.tz"/>
|
||||
<data android:host="maps.google.co.ug"/>
|
||||
<data android:host="maps.google.co.uk"/>
|
||||
<data android:host="maps.google.co.uz"/>
|
||||
<data android:host="maps.google.co.ve"/>
|
||||
<data android:host="maps.google.co.vi"/>
|
||||
<data android:host="maps.google.co.za"/>
|
||||
<data android:host="maps.google.co.zm"/>
|
||||
<data android:host="maps.google.co.zw"/>
|
||||
<data android:host="maps.google.com.af"/>
|
||||
<data android:host="maps.google.com.ag"/>
|
||||
<data android:host="maps.google.com.ai"/>
|
||||
<data android:host="maps.google.com.ar"/>
|
||||
<data android:host="maps.google.com.au"/>
|
||||
<data android:host="maps.google.com.bd"/>
|
||||
<data android:host="maps.google.com.bh"/>
|
||||
<data android:host="maps.google.com.bn"/>
|
||||
<data android:host="maps.google.com.bo"/>
|
||||
<data android:host="maps.google.com.br"/>
|
||||
<data android:host="maps.google.com.bz"/>
|
||||
<data android:host="maps.google.com.co"/>
|
||||
<data android:host="maps.google.com.cu"/>
|
||||
<data android:host="maps.google.com.cy"/>
|
||||
<data android:host="maps.google.com.do"/>
|
||||
<data android:host="maps.google.com.ec"/>
|
||||
<data android:host="maps.google.com.eg"/>
|
||||
<data android:host="maps.google.com.et"/>
|
||||
<data android:host="maps.google.com.fj"/>
|
||||
<data android:host="maps.google.com.gh"/>
|
||||
<data android:host="maps.google.com.gi"/>
|
||||
<data android:host="maps.google.com.gt"/>
|
||||
<data android:host="maps.google.com.hk"/>
|
||||
<data android:host="maps.google.com.jm"/>
|
||||
<data android:host="maps.google.com.kh"/>
|
||||
<data android:host="maps.google.com.kw"/>
|
||||
<data android:host="maps.google.com.lb"/>
|
||||
<data android:host="maps.google.com.ly"/>
|
||||
<data android:host="maps.google.com.mm"/>
|
||||
<data android:host="maps.google.com.mt"/>
|
||||
<data android:host="maps.google.com.mx"/>
|
||||
<data android:host="maps.google.com.my"/>
|
||||
<data android:host="maps.google.com.na"/>
|
||||
<data android:host="maps.google.com.ng"/>
|
||||
<data android:host="maps.google.com.ni"/>
|
||||
<data android:host="maps.google.com.np"/>
|
||||
<data android:host="maps.google.com.om"/>
|
||||
<data android:host="maps.google.com.pa"/>
|
||||
<data android:host="maps.google.com.pe"/>
|
||||
<data android:host="maps.google.com.pg"/>
|
||||
<data android:host="maps.google.com.ph"/>
|
||||
<data android:host="maps.google.com.pk"/>
|
||||
<data android:host="maps.google.com.pr"/>
|
||||
<data android:host="maps.google.com.py"/>
|
||||
<data android:host="maps.google.com.qa"/>
|
||||
<data android:host="maps.google.com.sa"/>
|
||||
<data android:host="maps.google.com.sb"/>
|
||||
<data android:host="maps.google.com.sg"/>
|
||||
<data android:host="maps.google.com.sl"/>
|
||||
<data android:host="maps.google.com.sv"/>
|
||||
<data android:host="maps.google.com.tj"/>
|
||||
<data android:host="maps.google.com.tr"/>
|
||||
<data android:host="maps.google.com.tw"/>
|
||||
<data android:host="maps.google.com.ua"/>
|
||||
<data android:host="maps.google.com.uy"/>
|
||||
<data android:host="maps.google.com.vc"/>
|
||||
<data android:host="maps.google.com.vn"/>
|
||||
<data android:host="maps.google.com"/>
|
||||
<data android:host="maps.google.cv"/>
|
||||
<data android:host="maps.google.cz"/>
|
||||
<data android:host="maps.google.de"/>
|
||||
<data android:host="maps.google.dj"/>
|
||||
<data android:host="maps.google.dk"/>
|
||||
<data android:host="maps.google.dm"/>
|
||||
<data android:host="maps.google.dz"/>
|
||||
<data android:host="maps.google.ee"/>
|
||||
<data android:host="maps.google.es"/>
|
||||
<data android:host="maps.google.fi"/>
|
||||
<data android:host="maps.google.fm"/>
|
||||
<data android:host="maps.google.fr"/>
|
||||
<data android:host="maps.google.ga"/>
|
||||
<data android:host="maps.google.ge"/>
|
||||
<data android:host="maps.google.gg"/>
|
||||
<data android:host="maps.google.gl"/>
|
||||
<data android:host="maps.google.gm"/>
|
||||
<data android:host="maps.google.gr"/>
|
||||
<data android:host="maps.google.gy"/>
|
||||
<data android:host="maps.google.hn"/>
|
||||
<data android:host="maps.google.hr"/>
|
||||
<data android:host="maps.google.ht"/>
|
||||
<data android:host="maps.google.hu"/>
|
||||
<data android:host="maps.google.ie"/>
|
||||
<data android:host="maps.google.im"/>
|
||||
<data android:host="maps.google.iq"/>
|
||||
<data android:host="maps.google.is"/>
|
||||
<data android:host="maps.google.it"/>
|
||||
<data android:host="maps.google.je"/>
|
||||
<data android:host="maps.google.jo"/>
|
||||
<data android:host="maps.google.kg"/>
|
||||
<data android:host="maps.google.ki"/>
|
||||
<data android:host="maps.google.kz"/>
|
||||
<data android:host="maps.google.la"/>
|
||||
<data android:host="maps.google.li"/>
|
||||
<data android:host="maps.google.lk"/>
|
||||
<data android:host="maps.google.lt"/>
|
||||
<data android:host="maps.google.lu"/>
|
||||
<data android:host="maps.google.lv"/>
|
||||
<data android:host="maps.google.md"/>
|
||||
<data android:host="maps.google.me"/>
|
||||
<data android:host="maps.google.mg"/>
|
||||
<data android:host="maps.google.mk"/>
|
||||
<data android:host="maps.google.ml"/>
|
||||
<data android:host="maps.google.mn"/>
|
||||
<data android:host="maps.google.ms"/>
|
||||
<data android:host="maps.google.mu"/>
|
||||
<data android:host="maps.google.mv"/>
|
||||
<data android:host="maps.google.mw"/>
|
||||
<data android:host="maps.google.ne"/>
|
||||
<data android:host="maps.google.nl"/>
|
||||
<data android:host="maps.google.no"/>
|
||||
<data android:host="maps.google.nr"/>
|
||||
<data android:host="maps.google.nu"/>
|
||||
<data android:host="maps.google.pl"/>
|
||||
<data android:host="maps.google.pn"/>
|
||||
<data android:host="maps.google.ps"/>
|
||||
<data android:host="maps.google.pt"/>
|
||||
<data android:host="maps.google.ro"/>
|
||||
<data android:host="maps.google.rs"/>
|
||||
<data android:host="maps.google.ru"/>
|
||||
<data android:host="maps.google.rw"/>
|
||||
<data android:host="maps.google.sc"/>
|
||||
<data android:host="maps.google.se"/>
|
||||
<data android:host="maps.google.sh"/>
|
||||
<data android:host="maps.google.si"/>
|
||||
<data android:host="maps.google.sk"/>
|
||||
<data android:host="maps.google.sm"/>
|
||||
<data android:host="maps.google.sn"/>
|
||||
<data android:host="maps.google.so"/>
|
||||
<data android:host="maps.google.sr"/>
|
||||
<data android:host="maps.google.st"/>
|
||||
<data android:host="maps.google.td"/>
|
||||
<data android:host="maps.google.tg"/>
|
||||
<data android:host="maps.google.tl"/>
|
||||
<data android:host="maps.google.tm"/>
|
||||
<data android:host="maps.google.tn"/>
|
||||
<data android:host="maps.google.to"/>
|
||||
<data android:host="maps.google.tt"/>
|
||||
<data android:host="maps.google.vg"/>
|
||||
<data android:host="maps.google.vu"/>
|
||||
<data android:host="maps.google.ws"/>
|
||||
<data android:host="www.googlemaps.com"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:pathPrefix="/maps"/>
|
||||
<!-- Generated from https://www.google.com/supported_domains //-->
|
||||
<data android:host="www.google.ad"/>
|
||||
<data android:host="www.google.ae"/>
|
||||
<data android:host="www.google.al"/>
|
||||
<data android:host="www.google.am"/>
|
||||
<data android:host="www.google.as"/>
|
||||
<data android:host="www.google.at"/>
|
||||
<data android:host="www.google.az"/>
|
||||
<data android:host="www.google.ba"/>
|
||||
<data android:host="www.google.be"/>
|
||||
<data android:host="www.google.bf"/>
|
||||
<data android:host="www.google.bg"/>
|
||||
<data android:host="www.google.bi"/>
|
||||
<data android:host="www.google.bj"/>
|
||||
<data android:host="www.google.bs"/>
|
||||
<data android:host="www.google.bt"/>
|
||||
<data android:host="www.google.by"/>
|
||||
<data android:host="www.google.ca"/>
|
||||
<data android:host="www.google.cat"/>
|
||||
<data android:host="www.google.cd"/>
|
||||
<data android:host="www.google.cf"/>
|
||||
<data android:host="www.google.cg"/>
|
||||
<data android:host="www.google.ch"/>
|
||||
<data android:host="www.google.ci"/>
|
||||
<data android:host="www.google.cl"/>
|
||||
<data android:host="www.google.cm"/>
|
||||
<data android:host="www.google.cn"/>
|
||||
<data android:host="www.google.co.ao"/>
|
||||
<data android:host="www.google.co.bw"/>
|
||||
<data android:host="www.google.co.ck"/>
|
||||
<data android:host="www.google.co.cr"/>
|
||||
<data android:host="www.google.co.id"/>
|
||||
<data android:host="www.google.co.il"/>
|
||||
<data android:host="www.google.co.in"/>
|
||||
<data android:host="www.google.co.jp"/>
|
||||
<data android:host="www.google.co.ke"/>
|
||||
<data android:host="www.google.co.kr"/>
|
||||
<data android:host="www.google.co.ls"/>
|
||||
<data android:host="www.google.co.ma"/>
|
||||
<data android:host="www.google.co.mz"/>
|
||||
<data android:host="www.google.co.nz"/>
|
||||
<data android:host="www.google.co.th"/>
|
||||
<data android:host="www.google.co.tz"/>
|
||||
<data android:host="www.google.co.ug"/>
|
||||
<data android:host="www.google.co.uk"/>
|
||||
<data android:host="www.google.co.uz"/>
|
||||
<data android:host="www.google.co.ve"/>
|
||||
<data android:host="www.google.co.vi"/>
|
||||
<data android:host="www.google.co.za"/>
|
||||
<data android:host="www.google.co.zm"/>
|
||||
<data android:host="www.google.co.zw"/>
|
||||
<data android:host="www.google.com.af"/>
|
||||
<data android:host="www.google.com.ag"/>
|
||||
<data android:host="www.google.com.ai"/>
|
||||
<data android:host="www.google.com.ar"/>
|
||||
<data android:host="www.google.com.au"/>
|
||||
<data android:host="www.google.com.bd"/>
|
||||
<data android:host="www.google.com.bh"/>
|
||||
<data android:host="www.google.com.bn"/>
|
||||
<data android:host="www.google.com.bo"/>
|
||||
<data android:host="www.google.com.br"/>
|
||||
<data android:host="www.google.com.bz"/>
|
||||
<data android:host="www.google.com.co"/>
|
||||
<data android:host="www.google.com.cu"/>
|
||||
<data android:host="www.google.com.cy"/>
|
||||
<data android:host="www.google.com.do"/>
|
||||
<data android:host="www.google.com.ec"/>
|
||||
<data android:host="www.google.com.eg"/>
|
||||
<data android:host="www.google.com.et"/>
|
||||
<data android:host="www.google.com.fj"/>
|
||||
<data android:host="www.google.com.gh"/>
|
||||
<data android:host="www.google.com.gi"/>
|
||||
<data android:host="www.google.com.gt"/>
|
||||
<data android:host="www.google.com.hk"/>
|
||||
<data android:host="www.google.com.jm"/>
|
||||
<data android:host="www.google.com.kh"/>
|
||||
<data android:host="www.google.com.kw"/>
|
||||
<data android:host="www.google.com.lb"/>
|
||||
<data android:host="www.google.com.ly"/>
|
||||
<data android:host="www.google.com.mm"/>
|
||||
<data android:host="www.google.com.mt"/>
|
||||
<data android:host="www.google.com.mx"/>
|
||||
<data android:host="www.google.com.my"/>
|
||||
<data android:host="www.google.com.na"/>
|
||||
<data android:host="www.google.com.ng"/>
|
||||
<data android:host="www.google.com.ni"/>
|
||||
<data android:host="www.google.com.np"/>
|
||||
<data android:host="www.google.com.om"/>
|
||||
<data android:host="www.google.com.pa"/>
|
||||
<data android:host="www.google.com.pe"/>
|
||||
<data android:host="www.google.com.pg"/>
|
||||
<data android:host="www.google.com.ph"/>
|
||||
<data android:host="www.google.com.pk"/>
|
||||
<data android:host="www.google.com.pr"/>
|
||||
<data android:host="www.google.com.py"/>
|
||||
<data android:host="www.google.com.qa"/>
|
||||
<data android:host="www.google.com.sa"/>
|
||||
<data android:host="www.google.com.sb"/>
|
||||
<data android:host="www.google.com.sg"/>
|
||||
<data android:host="www.google.com.sl"/>
|
||||
<data android:host="www.google.com.sv"/>
|
||||
<data android:host="www.google.com.tj"/>
|
||||
<data android:host="www.google.com.tr"/>
|
||||
<data android:host="www.google.com.tw"/>
|
||||
<data android:host="www.google.com.ua"/>
|
||||
<data android:host="www.google.com.uy"/>
|
||||
<data android:host="www.google.com.vc"/>
|
||||
<data android:host="www.google.com.vn"/>
|
||||
<data android:host="www.google.com"/>
|
||||
<data android:host="www.google.cv"/>
|
||||
<data android:host="www.google.cz"/>
|
||||
<data android:host="www.google.de"/>
|
||||
<data android:host="www.google.dj"/>
|
||||
<data android:host="www.google.dk"/>
|
||||
<data android:host="www.google.dm"/>
|
||||
<data android:host="www.google.dz"/>
|
||||
<data android:host="www.google.ee"/>
|
||||
<data android:host="www.google.es"/>
|
||||
<data android:host="www.google.fi"/>
|
||||
<data android:host="www.google.fm"/>
|
||||
<data android:host="www.google.fr"/>
|
||||
<data android:host="www.google.ga"/>
|
||||
<data android:host="www.google.ge"/>
|
||||
<data android:host="www.google.gg"/>
|
||||
<data android:host="www.google.gl"/>
|
||||
<data android:host="www.google.gm"/>
|
||||
<data android:host="www.google.gr"/>
|
||||
<data android:host="www.google.gy"/>
|
||||
<data android:host="www.google.hn"/>
|
||||
<data android:host="www.google.hr"/>
|
||||
<data android:host="www.google.ht"/>
|
||||
<data android:host="www.google.hu"/>
|
||||
<data android:host="www.google.ie"/>
|
||||
<data android:host="www.google.im"/>
|
||||
<data android:host="www.google.iq"/>
|
||||
<data android:host="www.google.is"/>
|
||||
<data android:host="www.google.it"/>
|
||||
<data android:host="www.google.je"/>
|
||||
<data android:host="www.google.jo"/>
|
||||
<data android:host="www.google.kg"/>
|
||||
<data android:host="www.google.ki"/>
|
||||
<data android:host="www.google.kz"/>
|
||||
<data android:host="www.google.la"/>
|
||||
<data android:host="www.google.li"/>
|
||||
<data android:host="www.google.lk"/>
|
||||
<data android:host="www.google.lt"/>
|
||||
<data android:host="www.google.lu"/>
|
||||
<data android:host="www.google.lv"/>
|
||||
<data android:host="www.google.md"/>
|
||||
<data android:host="www.google.me"/>
|
||||
<data android:host="www.google.mg"/>
|
||||
<data android:host="www.google.mk"/>
|
||||
<data android:host="www.google.ml"/>
|
||||
<data android:host="www.google.mn"/>
|
||||
<data android:host="www.google.ms"/>
|
||||
<data android:host="www.google.mu"/>
|
||||
<data android:host="www.google.mv"/>
|
||||
<data android:host="www.google.mw"/>
|
||||
<data android:host="www.google.ne"/>
|
||||
<data android:host="www.google.nl"/>
|
||||
<data android:host="www.google.no"/>
|
||||
<data android:host="www.google.nr"/>
|
||||
<data android:host="www.google.nu"/>
|
||||
<data android:host="www.google.pl"/>
|
||||
<data android:host="www.google.pn"/>
|
||||
<data android:host="www.google.ps"/>
|
||||
<data android:host="www.google.pt"/>
|
||||
<data android:host="www.google.ro"/>
|
||||
<data android:host="www.google.rs"/>
|
||||
<data android:host="www.google.ru"/>
|
||||
<data android:host="www.google.rw"/>
|
||||
<data android:host="www.google.sc"/>
|
||||
<data android:host="www.google.se"/>
|
||||
<data android:host="www.google.sh"/>
|
||||
<data android:host="www.google.si"/>
|
||||
<data android:host="www.google.sk"/>
|
||||
<data android:host="www.google.sm"/>
|
||||
<data android:host="www.google.sn"/>
|
||||
<data android:host="www.google.so"/>
|
||||
<data android:host="www.google.sr"/>
|
||||
<data android:host="www.google.st"/>
|
||||
<data android:host="www.google.td"/>
|
||||
<data android:host="www.google.tg"/>
|
||||
<data android:host="www.google.tl"/>
|
||||
<data android:host="www.google.tm"/>
|
||||
<data android:host="www.google.tn"/>
|
||||
<data android:host="www.google.to"/>
|
||||
<data android:host="www.google.tt"/>
|
||||
<data android:host="www.google.vg"/>
|
||||
<data android:host="www.google.vu"/>
|
||||
<data android:host="www.google.ws"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
|
||||
<data android:host="2gis.ae"/>
|
||||
<data android:host="2gis.az"/>
|
||||
<data android:host="2gis.cl"/>
|
||||
<data android:host="2gis.cl"/>
|
||||
<data android:host="2gis.com.cy"/>
|
||||
<data android:host="2gis.cz"/>
|
||||
<data android:host="2gis.it"/>
|
||||
<data android:host="2gis.kg"/>
|
||||
<data android:host="2gis.kz"/>
|
||||
<data android:host="2gis.ru"/>
|
||||
<data android:host="2gis.ua"/>
|
||||
<data android:host="2gis.uz"/>
|
||||
<data android:host="m.2gis.ae"/>
|
||||
<data android:host="m.2gis.az"/>
|
||||
<data android:host="m.2gis.cl"/>
|
||||
<data android:host="m.2gis.cl"/>
|
||||
<data android:host="m.2gis.com.cy"/>
|
||||
<data android:host="m.2gis.cz"/>
|
||||
<data android:host="m.2gis.it"/>
|
||||
<data android:host="m.2gis.kg"/>
|
||||
<data android:host="m.2gis.kz"/>
|
||||
<data android:host="m.2gis.ru"/>
|
||||
<data android:host="m.2gis.ua"/>
|
||||
<data android:host="m.2gis.uz"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
|
||||
<!-- #map=$zoom/$lat/$lon -->
|
||||
<data android:host="www.openstreetmap.org"/>
|
||||
<data android:path="/"/>
|
||||
<data android:path="/search"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data
|
||||
android:scheme="mapsme"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="data"/>
|
||||
<data android:host="*"/>
|
||||
<data android:mimeType="application/vnd.google-earth.kml+xml"/>
|
||||
<data android:mimeType="application/vnd.google-earth.kmz"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:mimeType="application/vnd.google-earth.kml+xml"/>
|
||||
<data android:mimeType="application/vnd.google-earth.kmz"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="data"/>
|
||||
<data android:host="*"/>
|
||||
<data android:mimeType="*/*"/>
|
||||
<!-- See http://stackoverflow.com/questions/3400072/pathpattern-to-match-file-extension-does-not-work-if-a-period-exists-elsewhere-i -->
|
||||
<data android:pathPattern="/.*\\.kmz" />
|
||||
<data android:pathPattern="/.*\\..*\\.kmz" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\.kmz" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\.kmz" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\..*\\.kmz" />
|
||||
<data android:pathPattern="/.*\\.kml" />
|
||||
<data android:pathPattern="/.*\\..*\\.kml" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\.kml" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\.kml" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\..*\\.kml" />
|
||||
<!-- Old MAPS.ME binary format //-->
|
||||
<data android:pathPattern="/.*\\.kmb" />
|
||||
<data android:pathPattern="/.*\\..*\\.kmb" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\.kmb" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\.kmb" />
|
||||
<data android:pathPattern="/.*\\..*\\..*\\..*\\..*\\.kmb" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.DownloadResourcesLegacyActivity"
|
||||
android:configChanges="screenLayout|screenSize"/>
|
||||
|
||||
<activity-alias
|
||||
android:name="app.organicmaps.DownloadResourcesActivity"
|
||||
android:label="@string/app_name"
|
||||
android:targetActivity="app.organicmaps.SplashActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.MwmActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"/>
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.downloader.DownloaderActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/download_maps"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.search.SearchActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/search_map"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity"
|
||||
android:windowSoftInputMode="stateVisible|adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.settings.SettingsActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/settings"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.help.HelpActivity"
|
||||
android:label="@string/about_menu_title"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="app.organicmaps.help.HelpActivity" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.bookmarks.BookmarkCategoriesActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/bookmarks"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.bookmarks.BookmarkListActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/bookmarks"
|
||||
android:parentActivityName="app.organicmaps.bookmarks.BookmarkCategoriesActivity"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.editor.EditorActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize"
|
||||
android:label="@string/edit_place"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.editor.ProfileActivity"
|
||||
android:parentActivityName="app.organicmaps.settings.SettingsActivity" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.editor.FeatureCategoryActivity"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.editor.ReportActivity"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.editor.OsmLoginActivity"
|
||||
android:parentActivityName="app.organicmaps.MwmActivity" />
|
||||
|
||||
<activity
|
||||
android:name="app.organicmaps.bookmarks.BookmarkCategorySettingsActivity"
|
||||
android:label="@string/list_settings"/>
|
||||
<activity
|
||||
android:name="app.organicmaps.widget.placepage.PlaceDescriptionActivity"
|
||||
android:label="@string/place_description_title"/>
|
||||
<activity
|
||||
android:name="app.organicmaps.settings.DrivingOptionsActivity"
|
||||
android:label="@string/driving_options_title"/>
|
||||
<service
|
||||
android:name="app.organicmaps.background.OsmUploadService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||
android:exported="false"/>
|
||||
|
||||
<!-- Catches app upgraded intent -->
|
||||
<receiver
|
||||
android:name=".background.UpgradeReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${FILE_PROVIDER_PLACEHOLDER}"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths">
|
||||
</meta-data>
|
||||
</provider>
|
||||
|
||||
<!-- Disable Google's checks for visited sites and loaded URLs in bookmarks description. -->
|
||||
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" />
|
||||
<!-- Disable Google's anonymous stats collection -->
|
||||
<meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" />
|
||||
|
||||
</application>
|
||||
</manifest>
|
|
@ -2,7 +2,7 @@ To build, install and run e.g. a Web Debug version on your device/emulator: './g
|
|||
|
||||
Or to compile a redistributable Fdroid Beta apk for testing: './gradlew assembleFdroidBeta'
|
||||
|
||||
Or to build release apks for all flavors: './gradlew assembleRelease'
|
||||
Or to build beta apks for all flavors: './gradlew assembleBeta'
|
||||
|
||||
To see all available build targets './gradlew tasks'
|
||||
|
||||
|
|
32
android/app/.gitignore
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
/build
|
||||
/nativeOutputs
|
||||
|
||||
# ignore private keys
|
||||
/google-services.json
|
||||
/secure.properties
|
||||
/release.keystore
|
||||
/secure.properties
|
||||
/libnotify.properties
|
||||
/google-services.json
|
||||
/google-play.json
|
||||
/firebase-app-distribution.json
|
||||
/firebase-test-lab.json
|
||||
/huawei-appgallery.json
|
||||
/src/main/res/xml/network_security_config.xml
|
||||
|
||||
# ignore flags symlinks
|
||||
/src/main/res/drawable-xhdpi/??.png
|
||||
/src/main/res/drawable-xhdpi/do_hack.png
|
||||
/src/main/res/drawable-xhdpi/uk_england.png
|
||||
/src/main/res/drawable-xhdpi/uk_northern_ireland.png
|
||||
/src/main/res/drawable-xhdpi/uk_scotland.png
|
||||
/src/main/res/drawable-xhdpi/uk_wales.png
|
||||
/src/main/res/drawable-mdpi/??.png
|
||||
/src/main/res/drawable-mdpi/do_hack.png
|
||||
/src/main/res/drawable-mdpi/uk_england.png
|
||||
/src/main/res/drawable-mdpi/uk_northern_ireland.png
|
||||
/src/main/res/drawable-mdpi/uk_scotland.png
|
||||
/src/main/res/drawable-mdpi/uk_wales.png
|
||||
|
||||
# ignore autogenerated metadata (see prepareGoogleReleaseListing in build.gradle)
|
||||
/src/google/play/listings
|
493
android/app/build.gradle
Normal file
|
@ -0,0 +1,493 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
//
|
||||
// The magic below is needed to disable Google Mobile Services (a.k.a GMS) and
|
||||
// Google Firebase Services during the build time. Unfortunately, the only way
|
||||
// to disable Gradle plugins is to add these hardcore switches to buildscript().
|
||||
//
|
||||
|
||||
// Detect flavors from the task name.
|
||||
def taskName = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
|
||||
def isFdroid = taskName.contains('fdroid')
|
||||
def isBeta = taskName.contains('beta')
|
||||
|
||||
//
|
||||
// Please add symlinks to google/java/app/organicmaps/location for each new gms-enabled flavor below:
|
||||
// ```
|
||||
// mkdir -p src/$flavor/java/app/organicmaps/
|
||||
// ln -sf ../../../../google/java/app/organicmaps/location src/$flavor/java/app/organicmaps/
|
||||
// ls -la src/$flavor/java/app/organicmaps/location/GoogleFusedLocationProvider.java
|
||||
// ```
|
||||
ext.googleMobileServicesEnabled = taskName.contains('google') || taskName.contains('huawei') || taskName.contains('web')
|
||||
|
||||
// Firebase Crashlytics compile-time feature flag: -Pfirebase=true|false
|
||||
def googleFirebaseServicesFlag = findProperty('firebase')
|
||||
// Enable Firebase for all beta flavors except fdroid only if google-services.json exists.
|
||||
def googleFirebaseServicesDefault = isBeta && !isFdroid && file("$projectDir/google-services.json").exists()
|
||||
ext.googleFirebaseServicesEnabled = googleFirebaseServicesFlag != null ?
|
||||
googleFirebaseServicesFlag == '' || googleFirebaseServicesFlag.toBoolean() :
|
||||
googleFirebaseServicesDefault
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.2.1'
|
||||
|
||||
if (googleMobileServicesEnabled) {
|
||||
println('Building with Google Mobile Services')
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
} else {
|
||||
println('Building without Google Services')
|
||||
}
|
||||
|
||||
if (googleFirebaseServicesEnabled) {
|
||||
println('Building with Google Firebase Services')
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
|
||||
classpath 'com.google.firebase:firebase-appdistribution-gradle:4.0.1'
|
||||
} else {
|
||||
println('Building without Google Firebase Services')
|
||||
}
|
||||
|
||||
classpath('com.github.triplet.gradle:play-publisher:3.8.6')
|
||||
classpath('ru.cian:huawei-publish-gradle-plugin:1.4.0')
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://www.jitpack.io' } // MPAndroidChart
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: 'secure.properties'
|
||||
if (googleMobileServicesEnabled) {
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
}
|
||||
if (googleFirebaseServicesEnabled) {
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
apply plugin: 'com.google.firebase.appdistribution'
|
||||
}
|
||||
apply plugin: 'com.github.triplet.play'
|
||||
apply plugin: 'ru.cian.huawei-publish-gradle-plugin'
|
||||
|
||||
dependencies {
|
||||
// Google Mobile Services
|
||||
if (googleMobileServicesEnabled) {
|
||||
implementation 'com.google.android.gms:play-services-location:21.0.1'
|
||||
}
|
||||
|
||||
// Google Firebase Services
|
||||
if (googleFirebaseServicesEnabled) {
|
||||
// Import the BoM for the Firebase platform
|
||||
implementation platform('com.google.firebase:firebase-bom:32.7.1')
|
||||
// Add the dependencies for the Crashlytics and Analytics libraries
|
||||
// When using the BoM, you don't specify versions in Firebase library dependencies
|
||||
implementation 'com.google.firebase:firebase-crashlytics'
|
||||
implementation 'com.google.firebase:firebase-crashlytics-ndk'
|
||||
}
|
||||
|
||||
// This line is added as a workaround for duplicate classes error caused by some outdated dependency:
|
||||
// > A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
|
||||
// We don't use Kotlin, but some dependencies are actively using it.
|
||||
// See https://stackoverflow.com/a/75719642
|
||||
implementation 'androidx.core:core:1.12.0'
|
||||
implementation(platform('org.jetbrains.kotlin:kotlin-bom:1.9.22'))
|
||||
implementation 'androidx.annotation:annotation:1.7.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.car.app:app:1.4.0-rc02'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.fragment:fragment:1.6.2'
|
||||
implementation 'androidx.preference:preference:1.2.1'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.3.2'
|
||||
implementation 'androidx.work:work-runtime:2.9.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.7.0'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
// Fix for app/organicmaps/util/FileUploadWorker.java:14: error: cannot access ListenableFuture
|
||||
// https://github.com/organicmaps/organicmaps/issues/6106
|
||||
implementation 'com.google.guava:guava:32.1.3-android'
|
||||
implementation 'com.github.devnullorthrow:MPAndroidChart:3.2.0-alpha'
|
||||
implementation 'net.jcip:jcip-annotations:1.0'
|
||||
|
||||
// Test Dependencies
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.mockito:mockito-core:5.8.0'
|
||||
testImplementation 'org.mockito:mockito-inline:5.2.0'
|
||||
}
|
||||
|
||||
def run(cmd) {
|
||||
def stdout = new ByteArrayOutputStream()
|
||||
exec {
|
||||
commandLine = cmd
|
||||
standardOutput = stdout
|
||||
}
|
||||
return stdout.toString()
|
||||
}
|
||||
|
||||
|
||||
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
|
||||
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
|
||||
|
||||
def getVersion() {
|
||||
def isWindows = DefaultNativePlatform.getCurrentOperatingSystem().isWindows()
|
||||
def bash = isWindows ? 'C:\\Program Files\\Git\\bin\\bash.exe' : 'bash'
|
||||
def versionCode = Integer.parseInt(run([bash, '../../tools/unix/version.sh', 'android_code']).trim())
|
||||
def versionName = run([bash, '../../tools/unix/version.sh', 'android_name']).trim()
|
||||
return new Tuple2(versionCode, versionName)
|
||||
}
|
||||
|
||||
def getCommitMessage() {
|
||||
return run(['git', '--no-pager', 'show', '-s', '--format=%s%n%n%b', 'HEAD']).trim()
|
||||
}
|
||||
|
||||
def osName = System.properties['os.name'].toLowerCase()
|
||||
|
||||
project.ext.appId = 'app.organicmaps'
|
||||
project.ext.appName = 'Organic Maps'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'app.organicmaps'
|
||||
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
// All properties are read from gradle.properties file
|
||||
compileSdk propCompileSdkVersion.toInteger()
|
||||
|
||||
ndkVersion '26.1.10909125'
|
||||
|
||||
defaultConfig {
|
||||
// Default package name is taken from the manifest and should be app.organicmaps
|
||||
def ver = getVersion()
|
||||
versionCode = ver.V1
|
||||
versionName = ver.V2
|
||||
println('Version: ' + versionName)
|
||||
println('VersionCode: ' + versionCode)
|
||||
minSdk propMinSdkVersion.toInteger()
|
||||
targetSdk propTargetSdkVersion.toInteger()
|
||||
applicationId project.ext.appId
|
||||
buildConfigField 'String', 'SUPPORT_MAIL', '"android@organicmaps.app"'
|
||||
// Should be customized in flavors.
|
||||
buildConfigField 'String', 'REVIEW_URL', '""'
|
||||
resourceConfigurations += [project.ext.supportedLocalizations]
|
||||
|
||||
externalNativeBuild {
|
||||
def pchFlag = 'OFF'
|
||||
if (project.hasProperty('pch')) pchFlag = 'ON'
|
||||
|
||||
def njobs = ''
|
||||
if (project.hasProperty('njobs')) njobs = project.getProperty('njobs')
|
||||
|
||||
cmake {
|
||||
cppFlags '-fexceptions', '-frtti'
|
||||
// There is no sense to enable sections without gcc's --gc-sections flag.
|
||||
cFlags '-fno-function-sections', '-fno-data-sections',
|
||||
'-Wno-extern-c-compat'
|
||||
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static',
|
||||
"-DOS=$osName", '-DSKIP_TESTS=ON', '-DSKIP_TOOLS=ON', "-DUSE_PCH=$pchFlag",
|
||||
"-DNJOBS=$njobs"
|
||||
targets 'organicmaps'
|
||||
}
|
||||
}
|
||||
|
||||
// Use, for example, -Parm32 gradle parameter to build only for armeabi-v7a.
|
||||
ndk {
|
||||
abiFilters = new HashSet<>()
|
||||
if (project.hasProperty('arm32') || project.hasProperty('armeabi-v7a')) {
|
||||
abiFilters.add('armeabi-v7a')
|
||||
}
|
||||
if (project.hasProperty('arm64') || project.hasProperty('arm64-v8a')) {
|
||||
abiFilters.add('arm64-v8a')
|
||||
}
|
||||
if (project.hasProperty('x86')) {
|
||||
abiFilters.add('x86')
|
||||
}
|
||||
if (project.hasProperty('x86_64') || project.hasProperty('x64')) {
|
||||
abiFilters.add('x86_64')
|
||||
}
|
||||
if (abiFilters.isEmpty()) {
|
||||
abiFilters.add('armeabi-v7a')
|
||||
abiFilters.add('arm64-v8a')
|
||||
// For the emulator, chromebooks and some Intel Atom devices.
|
||||
abiFilters.add('x86_64')
|
||||
}
|
||||
println('Building for ' + abiFilters + ' archs.')
|
||||
}
|
||||
|
||||
setProperty('archivesBaseName', appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode)
|
||||
}
|
||||
|
||||
flavorDimensions += 'default'
|
||||
|
||||
productFlavors {
|
||||
// 01 is a historical artefact, sorry.
|
||||
final int HUAWEI_VERSION_CODE_BASE = 01_00_00_00_00
|
||||
|
||||
google {
|
||||
dimension 'default'
|
||||
versionName = android.defaultConfig.versionName + '-Google'
|
||||
buildConfigField 'String', 'SUPPORT_MAIL', '"googleplay@organicmaps.app"'
|
||||
buildConfigField 'String', 'REVIEW_URL', '"market://details?id=app.organicmaps"'
|
||||
}
|
||||
|
||||
web {
|
||||
dimension 'default'
|
||||
versionName = android.defaultConfig.versionName + '-Web'
|
||||
buildConfigField 'String', 'SUPPORT_MAIL', '"apk@organicmaps.app"'
|
||||
}
|
||||
|
||||
fdroid {
|
||||
dimension 'default'
|
||||
versionName = android.defaultConfig.versionName + '-FDroid'
|
||||
buildConfigField 'String', 'SUPPORT_MAIL', '"fdroid@organicmaps.app"'
|
||||
}
|
||||
|
||||
huawei {
|
||||
dimension 'default'
|
||||
versionName = android.defaultConfig.versionName + '-Huawei'
|
||||
versionCode = HUAWEI_VERSION_CODE_BASE + android.defaultConfig.versionCode
|
||||
buildConfigField 'String', 'SUPPORT_MAIL', '"huawei@organicmaps.app"'
|
||||
buildConfigField 'String', 'REVIEW_URL', '"appmarket://details?id=app.organicmaps"'
|
||||
}
|
||||
}
|
||||
|
||||
playConfigs {
|
||||
googleRelease {
|
||||
enabled.set(true)
|
||||
}
|
||||
}
|
||||
|
||||
splits.abi {
|
||||
boolean enabled = project.hasProperty('splitApk')
|
||||
println ('Create separate apks: ' + enabled)
|
||||
enable enabled
|
||||
reset()
|
||||
include 'x86', 'armeabi-v7a', 'arm64-v8a', 'x86_64'
|
||||
universalApk true
|
||||
}
|
||||
|
||||
lint {
|
||||
disable 'MissingTranslation'
|
||||
// https://github.com/organicmaps/organicmaps/issues/3551
|
||||
disable 'MissingQuantity', 'UnusedQuantity'
|
||||
// https://github.com/organicmaps/organicmaps/issues/3550
|
||||
disable 'ByteOrderMark'
|
||||
// https://github.com/organicmaps/organicmaps/issues/1077
|
||||
disable 'CustomSplashScreen'
|
||||
// https://github.com/organicmaps/organicmaps/issues/3610
|
||||
disable 'InsecureBaseConfiguration'
|
||||
abortOnError true
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
android.applicationVariants.all { variant ->
|
||||
def task = variant.name.capitalize()
|
||||
project.task(type: Exec, "run${task}", dependsOn: "install${task}") {
|
||||
commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "$applicationId/app.organicmaps.DownloadResourcesActivity", '-a', 'android.intent.action.MAIN', '-c', 'android.intent.category.LAUNCHER'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
storePassword '12345678'
|
||||
keyAlias 'debug'
|
||||
keyPassword '12345678'
|
||||
}
|
||||
|
||||
release {
|
||||
storeFile file(spropStoreFile)
|
||||
storePassword spropStorePassword
|
||||
keyAlias spropKeyAlias
|
||||
keyPassword spropKeyPassword
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix '.debug' // Allows to install debug and release builds together
|
||||
versionNameSuffix '-debug'
|
||||
jniDebuggable true // Enable jni debug build
|
||||
zipAlignEnabled true
|
||||
signingConfig signingConfigs.debug
|
||||
resValue 'string', 'app_id', android.defaultConfig.applicationId + applicationIdSuffix
|
||||
resValue 'string', 'app_name', project.ext.appName + ' ' + '(Debug)'
|
||||
// Do not generate separate debug symbols for debug apps, because we don't distribute them.
|
||||
ndk.debugSymbolLevel = 'none'
|
||||
|
||||
if (googleFirebaseServicesEnabled) {
|
||||
// Keep debug symbols for test lab.
|
||||
ndk.debugSymbolLevel = 'symbol_table'
|
||||
firebaseCrashlytics {
|
||||
nativeSymbolUploadEnabled true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
// Includes the default ProGuard rules files that are packaged with the Android Gradle plugin.
|
||||
// To learn more, go to the documentation section about R8 configuration files.
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
resValue 'string', 'app_id', android.defaultConfig.applicationId
|
||||
resValue 'string', 'app_name', project.ext.appName
|
||||
// Full size symbols are too big for Google, 217mb aab vs 95mb.
|
||||
ndk.debugSymbolLevel = 'symbol_table'
|
||||
|
||||
if (googleFirebaseServicesEnabled) {
|
||||
firebaseCrashlytics {
|
||||
nativeSymbolUploadEnabled true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
beta {
|
||||
applicationIdSuffix '.beta'
|
||||
versionNameSuffix '-beta'
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
// Includes the default ProGuard rules files that are packaged with the Android Gradle plugin.
|
||||
// To learn more, go to the documentation section about R8 configuration files.
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
matchingFallbacks = ['debug', 'release']
|
||||
resValue 'string', 'app_id', android.defaultConfig.applicationId + applicationIdSuffix
|
||||
resValue 'string', 'app_name', project.ext.appName + ' ' + '(Beta)'
|
||||
// Full size symbols are too big for Google, 217mb aab vs 95mb.
|
||||
ndk.debugSymbolLevel = 'symbol_table'
|
||||
|
||||
if (googleFirebaseServicesEnabled) {
|
||||
firebaseCrashlytics {
|
||||
nativeSymbolUploadEnabled true
|
||||
}
|
||||
firebaseAppDistribution {
|
||||
// A new beta release is created for each commit.
|
||||
// Use the last commit message for the release notes.
|
||||
releaseNotes = getCommitMessage()
|
||||
groups = 'qa' // Notify only selected people.
|
||||
serviceCredentialsFile = "$projectDir/firebase-app-distribution.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.22.1+'
|
||||
buildStagingDirectory './nativeOutputs'
|
||||
path '../../CMakeLists.txt'
|
||||
}
|
||||
}
|
||||
|
||||
// We don't compress these extensions in assets/ because our random FileReader can't read zip-compressed files from apk.
|
||||
// TODO: Load all minor files via separate call to ReadAsString which can correctly handle compressed files in zip containers.
|
||||
androidResources {
|
||||
ignoreAssetsPattern '!.svn:!.git:!.DS_Store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~'
|
||||
noCompress = ['txt', 'bin', 'html', 'png', 'json', 'mwm', 'ttf', 'sdf', 'ui', 'config', 'csv', 'spv', 'obj']
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
packagingOptions.jniLibs {
|
||||
excludes += [
|
||||
'lib/**/libVkLayer_khronos_validation.so',
|
||||
'lib/**/libVkLayer_core_validation.so',
|
||||
'lib/**/libVkLayer_threading.so',
|
||||
'lib/**/libVkLayer_image.so',
|
||||
'lib/**/libVkLayer_parameter_validation.so',
|
||||
'lib/**/libVkLayer_object_tracker.so',
|
||||
'lib/**/libVkLayer_swapchain.so',
|
||||
'lib/**/libVkLayer_unique_objects.so',
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
|
||||
}
|
||||
|
||||
android.buildTypes.all { buildType ->
|
||||
def suffix = applicationIdSuffix != null ? applicationIdSuffix : ""
|
||||
def authorityValue = android.defaultConfig.applicationId + suffix + ".provider"
|
||||
def authority = "\"" + authorityValue + "\""
|
||||
buildConfigField 'String', 'FILE_PROVIDER_AUTHORITY', authority
|
||||
manifestPlaceholders += [FILE_PROVIDER_PLACEHOLDER : authorityValue]
|
||||
}
|
||||
|
||||
task prepareGoogleReleaseListing {
|
||||
// Prepares Google Play metainfo from F-Droid metainfo.
|
||||
final sourceFlavor = 'fdroid'
|
||||
final targetFlavor = 'google'
|
||||
doLast {
|
||||
final sourceDir = new File("${projectDir}/src/$sourceFlavor/play/listings")
|
||||
final targetDir = new File("${projectDir}/src/$targetFlavor/play/listings")
|
||||
final sourceFiles = fileTree(dir: sourceDir,
|
||||
include: '**/*.txt', exclude: "**/*-${targetFlavor}.txt")
|
||||
sourceFiles.each { File sourceFile ->
|
||||
final locale = sourceFile.parentFile.getName()
|
||||
final targetLocaleDir = new File(targetDir, locale)
|
||||
if (!targetLocaleDir.isDirectory())
|
||||
targetLocaleDir.mkdirs()
|
||||
final targetFile = new File(targetLocaleDir, sourceFile.getName())
|
||||
// Override Google-specific values by using ${name}-google.txt files.
|
||||
final overrideFile = new File(sourceFile.getPath().replace('.txt', "-${targetFlavor}.txt"))
|
||||
targetFile.text = overrideFile.exists() ? overrideFile.text : sourceFile.text
|
||||
}
|
||||
copy {
|
||||
from "${projectDir}/../../screenshots/android"
|
||||
into targetDir
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
play {
|
||||
enabled.set(false)
|
||||
track.set('production')
|
||||
userFraction.set(Double.valueOf(0.10)) // 10%
|
||||
defaultToAppBundles.set(true)
|
||||
releaseStatus.set(ReleaseStatus.IN_PROGRESS)
|
||||
serviceAccountCredentials.set(file('google-play.json'))
|
||||
}
|
||||
|
||||
huaweiPublish {
|
||||
instances {
|
||||
huaweiRelease {
|
||||
credentialsPath = "$projectDir/huawei-appgallery.json"
|
||||
buildFormat = 'aab'
|
||||
deployType = 'draft' // confirm manually
|
||||
releaseNotes = []
|
||||
def localeOverride = [
|
||||
'am' : 'am-ET',
|
||||
'gu': 'gu_IN',
|
||||
'iw-IL': 'he_IL',
|
||||
'kn-IN': 'kn_IN',
|
||||
'ml-IN': 'ml_IN',
|
||||
'mn-MN': 'mn_MN',
|
||||
'mr-IN': 'mr_IN',
|
||||
'ta-IN': 'ta_IN',
|
||||
'te-IN': 'te_IN',
|
||||
]
|
||||
def files = fileTree(dir: "$projectDir/src/fdroid/play/listings",
|
||||
include: '**/release-notes.txt')
|
||||
files.each { File file ->
|
||||
def path = file.getPath()
|
||||
def locale = file.parentFile.getName()
|
||||
locale = localeOverride.get(locale, locale)
|
||||
releaseNotes.add(new ru.cian.huawei.publish.ReleaseNote(locale, path))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
0
android/app/multidex-config.txt
Normal file
30
android/app/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
# For Guava used by Android Auto
|
||||
-dontwarn java.lang.reflect.AnnotatedType
|
||||
|
||||
# Disable obfuscation since it is open-source app.
|
||||
-dontobfuscate
|
||||
# R8 crypts the source line numbers in all log messages.
|
||||
# https://github.com/organicmaps/organicmaps/issues/6559#issuecomment-1812039926
|
||||
-dontoptimize
|
|
@ -0,0 +1,28 @@
|
|||
package app.organicmaps;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest
|
||||
{
|
||||
@Test
|
||||
public void useAppContext()
|
||||
{
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("app.organicmaps", appContext.getPackageName());
|
||||
}
|
||||
}
|
3
android/app/src/beta/AndroidManifest.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:gwpAsanMode="always" />
|
||||
</manifest>
|
BIN
android/app/src/beta/res/mipmap-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
android/app/src/beta/res/mipmap-hdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
android/app/src/beta/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
android/app/src/beta/res/mipmap-mdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
android/app/src/beta/res/mipmap-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
android/app/src/beta/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
android/app/src/beta/res/mipmap-xxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
android/app/src/beta/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#B97647</color>
|
||||
</resources>
|
3
android/app/src/debug/AndroidManifest.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:gwpAsanMode="always" />
|
||||
</manifest>
|
BIN
android/app/src/debug/res/mipmap-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
android/app/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
android/app/src/debug/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
android/app/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
android/app/src/debug/res/mipmap-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 36 KiB |