diff --git a/app/src/main/assets/licenses/atkinson_hyperlegible_ofl.txt b/app/src/main/assets/licenses/atkinson_hyperlegible_ofl.txt new file mode 100644 index 000000000..d60c8142f --- /dev/null +++ b/app/src/main/assets/licenses/atkinson_hyperlegible_ofl.txt @@ -0,0 +1,92 @@ +Copyright 2020 Braille Institute of America, Inc. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/src/main/assets/licenses/lexend_ofl.txt b/app/src/main/assets/licenses/lexend_ofl.txt new file mode 100644 index 000000000..ef5fbbc7c --- /dev/null +++ b/app/src/main/assets/licenses/lexend_ofl.txt @@ -0,0 +1,93 @@ +Copyright 2018 The Lexend Project Authors (https://github.com/googlefonts/lexend), with Reserved Font Name “RevReading Lexend”. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/src/main/assets/licenses/noto_sans_ofl.txt b/app/src/main/assets/licenses/noto_sans_ofl.txt new file mode 100644 index 000000000..7d7fbd8f7 --- /dev/null +++ b/app/src/main/assets/licenses/noto_sans_ofl.txt @@ -0,0 +1,93 @@ +Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/src/main/assets/licenses/nunito_sans_ofl.txt b/app/src/main/assets/licenses/nunito_sans_ofl.txt new file mode 100644 index 000000000..59f596f91 --- /dev/null +++ b/app/src/main/assets/licenses/nunito_sans_ofl.txt @@ -0,0 +1,93 @@ +Copyright 2016 The Nunito Sans Project Authors (https://github.com/Fonthausen/NunitoSans) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/src/main/assets/licenses/quicksand_ofl.txt b/app/src/main/assets/licenses/quicksand_ofl.txt new file mode 100644 index 000000000..c94d5ac36 --- /dev/null +++ b/app/src/main/assets/licenses/quicksand_ofl.txt @@ -0,0 +1,93 @@ +Copyright 2011 The Quicksand Project Authors (https://github.com/andrew-paglinawan/QuicksandFamily), with Reserved Font Name “Quicksand”. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/src/main/assets/licenses/roboto_condensed_ofl.txt b/app/src/main/assets/licenses/roboto_condensed_ofl.txt new file mode 100644 index 000000000..bafe4a2cf --- /dev/null +++ b/app/src/main/assets/licenses/roboto_condensed_ofl.txt @@ -0,0 +1,93 @@ +Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/src/main/assets/licenses/rubik_ofl.txt b/app/src/main/assets/licenses/rubik_ofl.txt new file mode 100644 index 000000000..5f14dbc9e --- /dev/null +++ b/app/src/main/assets/licenses/rubik_ofl.txt @@ -0,0 +1,93 @@ +Copyright 2015 The Rubik Project Authors (https://github.com/googlefonts/rubik) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/app/src/main/assets/licenses/subtitle_fonts_sources.txt b/app/src/main/assets/licenses/subtitle_fonts_sources.txt new file mode 100644 index 000000000..ba0420ffc --- /dev/null +++ b/app/src/main/assets/licenses/subtitle_fonts_sources.txt @@ -0,0 +1,39 @@ +Bundled subtitle fonts +Source repository: https://github.com/google/fonts +Retrieved from the google/fonts main branch for this build. + +Noto Sans + https://raw.githubusercontent.com/google/fonts/main/ofl/notosans/NotoSans%5Bwdth%2Cwght%5D.ttf + SHA-256: bfb7bb691513f12e734dc346c03a03f784912432d7e3fa8e56efcf906fe86b3d + +Atkinson Hyperlegible Regular + https://raw.githubusercontent.com/google/fonts/main/ofl/atkinsonhyperlegible/AtkinsonHyperlegible-Regular.ttf + SHA-256: 7fb917c89019896d0b52ee84b7cbb3304c18cb90b19a62f5e32712bd23e97669 + +Atkinson Hyperlegible Bold + https://raw.githubusercontent.com/google/fonts/main/ofl/atkinsonhyperlegible/AtkinsonHyperlegible-Bold.ttf + SHA-256: 5a3b0c8cc8ca545155150b4512a1fa248298df121c50d6557e651e61fbdab92f + +Lexend + https://raw.githubusercontent.com/google/fonts/main/ofl/lexend/Lexend%5Bwght%5D.ttf + SHA-256: 3add53e641fbc81da64da4bb254285e2831b52b029527bc0714e2b9610832ee6 + +Roboto Condensed + https://raw.githubusercontent.com/google/fonts/main/ofl/robotocondensed/RobotoCondensed%5Bwght%5D.ttf + SHA-256: dace262afcee68a5276f200d8026c57221735c0118ab5fda8c2c0d3dc409a8d0 + +Nunito Sans + https://raw.githubusercontent.com/google/fonts/main/ofl/nunitosans/NunitoSans%5BYTLC%2Copsz%2Cwdth%2Cwght%5D.ttf + SHA-256: f934d7142fb4784bf828da485b7dcbd90c0c80d514e9d49a5da0ed3a1ae2491d + +Quicksand + https://raw.githubusercontent.com/google/fonts/main/ofl/quicksand/Quicksand%5Bwght%5D.ttf + SHA-256: 39c9b64223561f56aaff6062a6f04063c4fc86809ad6768722c06614d977e1cc + +Rubik + https://raw.githubusercontent.com/google/fonts/main/ofl/rubik/Rubik%5Bwght%5D.ttf + SHA-256: 1b3a7437ba2af80e465e773ed60c5036d1ba6ace492d89046dbcf18fb31e4e88 + +Varela Round + https://raw.githubusercontent.com/google/fonts/main/ofl/varelaround/VarelaRound-Regular.ttf + SHA-256: e1e47eb66dbc2ddc106661338e712d9176c9e83c669a82fde155324823d03aa2 diff --git a/app/src/main/assets/licenses/varela_round_ofl.txt b/app/src/main/assets/licenses/varela_round_ofl.txt new file mode 100644 index 000000000..8d049ec8f --- /dev/null +++ b/app/src/main/assets/licenses/varela_round_ofl.txt @@ -0,0 +1,93 @@ +Copyright 2023 The Varela Round Project Authors (https://github.com/alefalefalef/Varela-Round-Hebrew/), with Reserved Font Names 'Varela' and ‘Varela Round’. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/app/src/main/kotlin/com/arflix/tv/data/repository/CloudSyncRepository.kt b/app/src/main/kotlin/com/arflix/tv/data/repository/CloudSyncRepository.kt index d450d7ba1..d3052438a 100644 --- a/app/src/main/kotlin/com/arflix/tv/data/repository/CloudSyncRepository.kt +++ b/app/src/main/kotlin/com/arflix/tv/data/repository/CloudSyncRepository.kt @@ -271,6 +271,7 @@ class CloudSyncRepository @Inject constructor( val subtitleSize: String = "Medium", val subtitleColor: String = "White", val subtitleStyle: String = "Bold", + val subtitleFont: String = "System", val subtitleOffset: String = "Bottom", val subtitleStylized: Boolean = true, val cardLayoutMode: String = CARD_LAYOUT_MODE_LANDSCAPE, @@ -338,6 +339,8 @@ class CloudSyncRepository @Inject constructor( profileManager.profileStringKeyFor(profileId, "subtitle_offset") private fun subtitleStyleKeyFor(profileId: String) = profileManager.profileStringKeyFor(profileId, "subtitle_style") + private fun subtitleFontKeyFor(profileId: String) = + profileManager.profileStringKeyFor(profileId, "subtitle_font") private fun subtitleStylizedKeyFor(profileId: String) = profileManager.profileBooleanKeyFor(profileId, "subtitle_stylized") private fun iptvHiddenGroupsKeyFor(profileId: String) = @@ -631,6 +634,7 @@ class CloudSyncRepository @Inject constructor( subtitleColor = prefs[subtitleColorKeyFor(profile.id)] ?: "White", subtitleOffset = prefs[subtitleOffsetKeyFor(profile.id)] ?: "Bottom", subtitleStyle = prefs[subtitleStyleKeyFor(profile.id)] ?: "Bold", + subtitleFont = prefs[subtitleFontKeyFor(profile.id)] ?: "System", subtitleStylized = prefs[subtitleStylizedKeyFor(profile.id)] ?: true, secondarySubtitle = prefs[secondarySubtitleKeyFor(profile.id)] ?: "Off", filterSubtitlesByLanguage = prefs[filterSubtitlesByLanguageKeyFor(profile.id)] ?: true, @@ -1344,6 +1348,7 @@ class CloudSyncRepository @Inject constructor( prefs[subtitleColorKeyFor(profileId)] = state.subtitleColor prefs[subtitleOffsetKeyFor(profileId)] = state.subtitleOffset prefs[subtitleStyleKeyFor(profileId)] = state.subtitleStyle + prefs[subtitleFontKeyFor(profileId)] = state.subtitleFont prefs[subtitleStylizedKeyFor(profileId)] = state.subtitleStylized prefs[secondarySubtitleKeyFor(profileId)] = state.secondarySubtitle.ifBlank { "Off" } prefs[filterSubtitlesByLanguageKeyFor(profileId)] = state.filterSubtitlesByLanguage diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerScreen.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerScreen.kt index 816854b66..7211b2fa1 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerScreen.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerScreen.kt @@ -2657,8 +2657,8 @@ fun PlayerScreen( val subtitleSizePref = uiState.subtitleSize val subtitleColorPref = uiState.subtitleColor val subtitleStylePref = uiState.subtitleStyle + val subtitleFontPref = uiState.subtitleFont val subtitleStylizedPref = uiState.subtitleStylized - val subtitleOffsetPref = uiState.subtitleOffset val aspectModeLabel = when (playerResizeMode) { AspectRatioFrameLayout.RESIZE_MODE_ZOOM -> "Zoom" AspectRatioFrameLayout.RESIZE_MODE_FILL -> "Fill" @@ -3150,61 +3150,17 @@ fun PlayerScreen( // Enable subtitle view with styling based on user preference subtitleView?.apply { - val subSizeSp = when (subtitleSizePref) { - "Small" -> 18f; "Large" -> 30f; "Extra Large" -> 36f; else -> 24f - } - val subFgColor = when (subtitleColorPref) { - "Yellow" -> android.graphics.Color.YELLOW - "Green" -> android.graphics.Color.GREEN - "Cyan" -> android.graphics.Color.CYAN - else -> android.graphics.Color.WHITE - } - val subTypeface = when (subtitleStylePref) { - "Normal" -> android.graphics.Typeface.DEFAULT - "Background" -> android.graphics.Typeface.DEFAULT_BOLD - else -> android.graphics.Typeface.DEFAULT_BOLD - } - val subEdgeType = when (subtitleStylePref) { - "Normal" -> androidx.media3.ui.CaptionStyleCompat.EDGE_TYPE_NONE - "Background" -> androidx.media3.ui.CaptionStyleCompat.EDGE_TYPE_NONE - else -> androidx.media3.ui.CaptionStyleCompat.EDGE_TYPE_OUTLINE - } - val subBgColor = when (subtitleStylePref) { - "Background" -> android.graphics.Color.argb(180, 0, 0, 0) - else -> android.graphics.Color.TRANSPARENT - } - setStyle( - androidx.media3.ui.CaptionStyleCompat( - subFgColor, - android.graphics.Color.TRANSPARENT, - subBgColor, - subEdgeType, - android.graphics.Color.BLACK, - subTypeface - ) + applySubtitleAppearance( + context = ctx, + sizePreference = subtitleSizePref, + sizePercent = subtitleSizePct, + verticalPercent = subtitleVerticalPct, + colorPreference = subtitleColorPref, + stylePreference = subtitleStylePref, + fontPreference = subtitleFontPref, + preserveEmbeddedStyles = subtitleStylizedPref, + inPictureInPicture = isInPipMode, ) - val pipSubScale = if (isInPipMode) 0.4f else 1f - setFixedTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, subSizeSp * pipSubScale) - val bottomPaddingFraction = when (subtitleOffsetPref) { - "Bottom" -> 0.02f - "Low" -> 0.08f - "Medium" -> 0.15f - "High" -> 0.25f - else -> 0.02f - } - setBottomPaddingFraction(bottomPaddingFraction) - - if (subtitleStylizedPref) { - // Stylized mode: let Media3 render embedded ASS/SSA styles - // (colors, fonts, positioning, z-order). User prefs are - // only used as a fallback CaptionStyle for plain SRT/VTT. - setApplyEmbeddedStyles(true) - setApplyEmbeddedFontSizes(true) - } else { - // Uniform mode: override everything with user preferences - setApplyEmbeddedStyles(false) - setApplyEmbeddedFontSizes(false) - } } } }, @@ -3214,12 +3170,17 @@ fun PlayerScreen( playerView.resizeMode = playerResizeMode playerView.setUseVideoFrameForSubtitles(useVideoFrameSubtitleViewport) playerView.subtitleView?.apply { - val baseSizeSp = when (subtitleSizePref) { - "Small" -> 18f; "Large" -> 30f; "Extra Large" -> 36f; else -> 24f - } - val pipSubScale = if (isInPipMode) 0.4f else 1f - setFixedTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, baseSizeSp * (subtitleSizePct / 100f) * pipSubScale) - setBottomPaddingFraction((subtitleVerticalPct / 100f).coerceIn(0f, 0.5f)) + applySubtitleAppearance( + context = playerView.context, + sizePreference = subtitleSizePref, + sizePercent = subtitleSizePct, + verticalPercent = subtitleVerticalPct, + colorPreference = subtitleColorPref, + stylePreference = subtitleStylePref, + fontPreference = subtitleFontPref, + preserveEmbeddedStyles = subtitleStylizedPref, + inPictureInPicture = isInPipMode, + ) // "Find best match" without AI showing selects the built-in reference // track under the hood to read its timing — hide its raw (e.g. English) // cues while the scan runs. Display-only: the scan's cue collection diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerViewModel.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerViewModel.kt index a33838755..786e57e09 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerViewModel.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/PlayerViewModel.kt @@ -122,6 +122,7 @@ data class PlayerUiState( val subtitleSize: String = "Medium", val subtitleColor: String = "White", val subtitleStyle: String = "Bold", + val subtitleFont: String = SubtitleFontOption.DefaultPreference, val subtitleStylized: Boolean = true, val subtitleOffset: String = "Bottom", val error: String? = null, @@ -569,6 +570,9 @@ class PlayerViewModel @Inject constructor( val subSize = prefs[profileManager.profileStringKey("subtitle_size")] ?: "Medium" val subColor = prefs[profileManager.profileStringKey("subtitle_color")] ?: "White" val subStyle = prefs[profileManager.profileStringKey("subtitle_style")] ?: "Bold" + val subFont = SubtitleFontOption.fromPreference( + prefs[profileManager.profileStringKey("subtitle_font")] + ).preferenceValue val subStylized = prefs[profileManager.profileBooleanKey("subtitle_stylized")] ?: true val subOffset = prefs[profileManager.profileStringKey("subtitle_offset")] ?: "Bottom" val autoPlayNext = prefs[autoPlayNextKey()] ?: true @@ -619,6 +623,7 @@ class PlayerViewModel @Inject constructor( subtitleSize = subSize, subtitleColor = subColor, subtitleStyle = subStyle, + subtitleFont = subFont, subtitleStylized = subStylized, subtitleOffset = subOffset, autoPlayNext = autoPlayNext, diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleFontOption.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleFontOption.kt new file mode 100644 index 000000000..25eacb176 --- /dev/null +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleFontOption.kt @@ -0,0 +1,37 @@ +package com.arflix.tv.ui.screens.player + +/** Fonts bundled specifically for subtitle rendering. */ +enum class SubtitleFontOption(val preferenceValue: String) { + SYSTEM("System"), + NOTO_SANS("Noto Sans"), + ATKINSON_HYPERLEGIBLE("Atkinson Hyperlegible"), + LEXEND("Lexend"), + ROBOTO_CONDENSED("Roboto Condensed"), + NUNITO_SANS("Nunito Sans"), + QUICKSAND("Quicksand"), + RUBIK("Rubik"), + VARELA_ROUND("Varela Round"); + + companion object { + const val DefaultPreference = "System" + + fun fromPreference(value: String?): SubtitleFontOption = + entries.firstOrNull { it.preferenceValue == value } ?: SYSTEM + + fun nextPreference(value: String?): String { + val current = fromPreference(value) + return entries[(current.ordinal + 1) % entries.size].preferenceValue + } + + fun previousPreference(value: String?): String { + val current = fromPreference(value) + return entries[(current.ordinal - 1 + entries.size) % entries.size].preferenceValue + } + } +} + +internal fun shouldPreserveEmbeddedSubtitleStyles( + fontPreference: String?, + stylizedSubtitlesEnabled: Boolean, +): Boolean = stylizedSubtitlesEnabled && + SubtitleFontOption.fromPreference(fontPreference) == SubtitleFontOption.SYSTEM diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleTypefaceResolver.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleTypefaceResolver.kt new file mode 100644 index 000000000..273f3ac89 --- /dev/null +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleTypefaceResolver.kt @@ -0,0 +1,28 @@ +package com.arflix.tv.ui.screens.player + +import android.content.Context +import android.graphics.Typeface +import androidx.annotation.FontRes +import androidx.core.content.res.ResourcesCompat +import com.arflix.tv.R + +internal fun resolveSubtitleTypeface( + context: Context, + preference: String?, + bold: Boolean, +): Typeface { + val option = SubtitleFontOption.fromPreference(preference) + @FontRes val fontRes = when (option) { + SubtitleFontOption.SYSTEM -> null + SubtitleFontOption.NOTO_SANS -> R.font.noto_sans_variable + SubtitleFontOption.ATKINSON_HYPERLEGIBLE -> R.font.atkinson_hyperlegible + SubtitleFontOption.LEXEND -> R.font.lexend_variable + SubtitleFontOption.ROBOTO_CONDENSED -> R.font.roboto_condensed_variable + SubtitleFontOption.NUNITO_SANS -> R.font.nunito_sans_variable + SubtitleFontOption.QUICKSAND -> R.font.quicksand_variable + SubtitleFontOption.RUBIK -> R.font.rubik_variable + SubtitleFontOption.VARELA_ROUND -> R.font.varela_round_regular + } + val base = fontRes?.let { ResourcesCompat.getFont(context, it) } ?: Typeface.DEFAULT + return Typeface.create(base, if (bold) Typeface.BOLD else Typeface.NORMAL) +} diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleViewStyling.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleViewStyling.kt new file mode 100644 index 000000000..1fdfda02d --- /dev/null +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/player/SubtitleViewStyling.kt @@ -0,0 +1,69 @@ +package com.arflix.tv.ui.screens.player + +import android.content.Context +import android.graphics.Color +import android.util.TypedValue +import androidx.media3.ui.CaptionStyleCompat +import androidx.media3.ui.SubtitleView + +internal fun SubtitleView.applySubtitleAppearance( + context: Context, + sizePreference: String, + sizePercent: Int, + verticalPercent: Int, + colorPreference: String, + stylePreference: String, + fontPreference: String, + preserveEmbeddedStyles: Boolean, + inPictureInPicture: Boolean, +) { + val baseSizeSp = when (sizePreference) { + "Small" -> 18f + "Large" -> 30f + "Extra Large" -> 36f + else -> 24f + } + val foregroundColor = when (colorPreference) { + "Yellow" -> Color.YELLOW + "Green" -> Color.GREEN + "Cyan" -> Color.CYAN + else -> Color.WHITE + } + val edgeType = when (stylePreference) { + "Normal", "Background" -> CaptionStyleCompat.EDGE_TYPE_NONE + else -> CaptionStyleCompat.EDGE_TYPE_OUTLINE + } + val windowColor = if (stylePreference == "Background") { + Color.argb(180, 0, 0, 0) + } else { + Color.TRANSPARENT + } + val typeface = resolveSubtitleTypeface( + context = context, + preference = fontPreference, + bold = stylePreference != "Normal", + ) + + setStyle( + CaptionStyleCompat( + foregroundColor, + Color.TRANSPARENT, + windowColor, + edgeType, + Color.BLACK, + typeface, + ) + ) + val pipScale = if (inPictureInPicture) 0.4f else 1f + setFixedTextSize( + TypedValue.COMPLEX_UNIT_SP, + baseSizeSp * (sizePercent.coerceIn(50, 300) / 100f) * pipScale, + ) + setBottomPaddingFraction((verticalPercent / 100f).coerceIn(0f, 0.5f)) + val applyEmbeddedStyles = shouldPreserveEmbeddedSubtitleStyles( + fontPreference = fontPreference, + stylizedSubtitlesEnabled = preserveEmbeddedStyles, + ) + setApplyEmbeddedStyles(applyEmbeddedStyles) + setApplyEmbeddedFontSizes(applyEmbeddedStyles) +} diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt index 93756425d..3716da83f 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsScreen.kt @@ -249,7 +249,7 @@ private val tvGeneralSectionIds = setOf( private fun tvGeneralRowsForSection(section: String): List { return when (section) { "language" -> listOf(0, 3, 1, 2) - "subtitles" -> listOf(4, 5, 6, 7, 8, 38, 39, 9) + "subtitles" -> listOf(4, 5, 6, 7, 42, 8, 38, 39, 9) "ai_subtitles" -> listOf(28, 29, 30, 31, 32, 33) "playback" -> listOf(10, 11, 12, 13, 14, 37, 34, 16, 15, 40, 27) "appearance" -> listOf(17, 18, 20, 21, 24, 23, 22, 41, 36) @@ -958,6 +958,7 @@ fun SettingsScreen( 5 -> viewModel.cycleSubtitleColor() 6 -> viewModel.cycleSubtitleOffset() 7 -> viewModel.cycleSubtitleStyle() + 42 -> viewModel.cycleSubtitleFont() 8 -> viewModel.toggleSubtitleStylized() 9 -> viewModel.setFilterSubtitlesByLanguage(!uiState.filterSubtitlesByLanguage) 10 -> viewModel.setAutoPlayNext(!uiState.autoPlayNext) @@ -1458,6 +1459,7 @@ fun SettingsScreen( subtitleColor = uiState.subtitleColor, subtitleOffset = uiState.subtitleOffset, subtitleStyle = uiState.subtitleStyle, + subtitleFont = uiState.subtitleFont, subtitleStylized = uiState.subtitleStylized, deviceModeOverride = uiState.deviceModeOverride, skipProfileSelection = uiState.skipProfileSelection, @@ -1504,6 +1506,7 @@ fun SettingsScreen( onSubtitleColorClick = { viewModel.cycleSubtitleColor() }, onSubtitleOffsetClick = { viewModel.cycleSubtitleOffset() }, onSubtitleStyleClick = { viewModel.cycleSubtitleStyle() }, + onSubtitleFontClick = { viewModel.cycleSubtitleFont() }, onSubtitleStylizedToggle = { viewModel.toggleSubtitleStylized() }, filterSubtitlesByLanguage = uiState.filterSubtitlesByLanguage, onFilterSubtitlesByLanguageToggle = { viewModel.setFilterSubtitlesByLanguage(it) }, @@ -4304,6 +4307,14 @@ private fun MobileSettingsSubPage( isFocused = false, onClick = { viewModel.cycleSubtitleStyle() } ) + MobileSettingsRow( + icon = Icons.Default.Subtitles, + title = stringResource(R.string.subtitle_font), + subtitle = stringResource(R.string.subtitle_font_desc), + value = uiState.subtitleFont, + isFocused = false, + onClick = { viewModel.cycleSubtitleFont() } + ) MobileSettingsRow( icon = Icons.Default.Subtitles, title = stringResource(R.string.subtitle_stylized), @@ -5494,6 +5505,7 @@ private fun TvGeneralSettingsRows( subtitleColor: String = "White", subtitleOffset: String = "Low", subtitleStyle: String = "Bold", + subtitleFont: String = "System", deviceModeOverride: String = "auto", skipProfileSelection: Boolean = false, oledBlackBackground: Boolean = false, @@ -5533,6 +5545,7 @@ private fun TvGeneralSettingsRows( onSubtitleColorClick: () -> Unit = {}, onSubtitleOffsetClick: () -> Unit = {}, onSubtitleStyleClick: () -> Unit = {}, + onSubtitleFontClick: () -> Unit = {}, subtitleStylized: Boolean = true, onSubtitleStylizedToggle: () -> Unit = {}, filterSubtitlesByLanguage: Boolean = true, @@ -5609,6 +5622,7 @@ private fun TvGeneralSettingsRows( 5 -> SettingsRow(Icons.Default.Subtitles, stringResource(R.string.subtitle_color), stringResource(R.string.subtitle_color_desc), subtitleColor, focusedIndex == localIndex, onSubtitleColorClick, Modifier.settingsFocusSlot(localIndex)) 6 -> SettingsRow(Icons.Default.Subtitles, stringResource(R.string.subtitle_offset), stringResource(R.string.subtitle_offset_desc), subtitleOffset, focusedIndex == localIndex, onSubtitleOffsetClick, Modifier.settingsFocusSlot(localIndex)) 7 -> SettingsRow(Icons.Default.Subtitles, stringResource(R.string.subtitle_style), stringResource(R.string.subtitle_style_desc), subtitleStyle, focusedIndex == localIndex, onSubtitleStyleClick, Modifier.settingsFocusSlot(localIndex)) + 42 -> SettingsRow(Icons.Default.Subtitles, stringResource(R.string.subtitle_font), stringResource(R.string.subtitle_font_desc), subtitleFont, focusedIndex == localIndex, onSubtitleFontClick, Modifier.settingsFocusSlot(localIndex)) 8 -> SettingsToggleRow(stringResource(R.string.subtitle_stylized), stringResource(R.string.subtitle_stylized_desc), subtitleStylized, focusedIndex == localIndex, { onSubtitleStylizedToggle() }, Modifier.settingsFocusSlot(localIndex)) 9 -> SettingsToggleRow(stringResource(R.string.filter_subtitles), stringResource(R.string.filter_subtitles_desc), filterSubtitlesByLanguage, focusedIndex == localIndex, onFilterSubtitlesByLanguageToggle, Modifier.settingsFocusSlot(localIndex)) 10 -> SettingsToggleRow(stringResource(R.string.auto_play_next_title), stringResource(R.string.auto_play_desc), autoPlayNext, focusedIndex == localIndex, onAutoPlayToggle, Modifier.settingsFocusSlot(localIndex)) @@ -5735,6 +5749,7 @@ private fun GeneralSettings( onSubtitleColorClick: () -> Unit = {}, onSubtitleOffsetClick: () -> Unit = {}, onSubtitleStyleClick: () -> Unit = {}, + onSubtitleFontClick: () -> Unit = {}, subtitleStylized: Boolean = true, onSubtitleStylizedToggle: () -> Unit = {}, filterSubtitlesByLanguage: Boolean = true, diff --git a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsViewModel.kt b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsViewModel.kt index 8935dfbdd..475c545fc 100644 --- a/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsViewModel.kt +++ b/app/src/main/kotlin/com/arflix/tv/ui/screens/settings/SettingsViewModel.kt @@ -11,6 +11,7 @@ import androidx.lifecycle.viewModelScope import com.arflix.tv.R import com.arflix.tv.server.AiKeyConfigServer import com.arflix.tv.ui.screens.player.SubtitleAiModel +import com.arflix.tv.ui.screens.player.SubtitleFontOption import com.arflix.tv.util.AppLogger import com.arflix.tv.util.DeviceIpAddress import com.arflix.tv.util.DiagnosticsManager @@ -108,6 +109,7 @@ data class SettingsUiState( val subtitleSize: String = "Medium", val subtitleColor: String = "White", val subtitleStyle: String = "Bold", + val subtitleFont: String = SubtitleFontOption.DefaultPreference, val subtitleOffset: String = "Bottom", val subtitleStylized: Boolean = true, val filterSubtitlesByLanguage: Boolean = true, @@ -317,6 +319,7 @@ class SettingsViewModel @Inject constructor( private fun subtitleColorKey() = profileManager.profileStringKey("subtitle_color") private fun subtitleOffsetKey() = profileManager.profileStringKey("subtitle_offset") private fun subtitleStyleKey() = profileManager.profileStringKey("subtitle_style") + private fun subtitleFontKey() = profileManager.profileStringKey("subtitle_font") private fun subtitleStylizedKey() = profileManager.profileBooleanKey("subtitle_stylized") private fun filterSubtitlesByLanguageKey() = profileManager.profileBooleanKey("filter_subtitles_by_lang") private fun secondarySubtitleKey() = profileManager.profileStringKey("secondary_subtitle") @@ -529,6 +532,7 @@ class SettingsViewModel @Inject constructor( val subtitleSize = prefs[subtitleSizeKey()] ?: "Medium" val subtitleColor = prefs[subtitleColorKey()] ?: "White" val subtitleStyle = prefs[subtitleStyleKey()] ?: "Bold" + val subtitleFont = SubtitleFontOption.fromPreference(prefs[subtitleFontKey()]).preferenceValue val subtitleOffset = prefs[subtitleOffsetKey()] ?: "Bottom" val subtitleStylized = prefs[subtitleStylizedKey()] ?: true val filterSubtitlesByLanguage = prefs[filterSubtitlesByLanguageKey()] ?: true @@ -620,6 +624,7 @@ class SettingsViewModel @Inject constructor( subtitleSize = subtitleSize, subtitleColor = subtitleColor, subtitleStyle = subtitleStyle, + subtitleFont = subtitleFont, subtitleOffset = subtitleOffset, subtitleStylized = subtitleStylized, filterSubtitlesByLanguage = filterSubtitlesByLanguage, @@ -1475,6 +1480,15 @@ class SettingsViewModel @Inject constructor( viewModelScope.launch { context.settingsDataStore.edit { it[subtitleStyleKey()] = next }; _uiState.value = _uiState.value.copy(subtitleStyle = next); syncLocalStateToCloud(silent = true) } } + fun cycleSubtitleFont() { + val next = SubtitleFontOption.nextPreference(_uiState.value.subtitleFont) + viewModelScope.launch { + context.settingsDataStore.edit { it[subtitleFontKey()] = next } + _uiState.value = _uiState.value.copy(subtitleFont = next) + syncLocalStateToCloud(silent = true) + } + } + fun toggleSubtitleStylized() { val next = !_uiState.value.subtitleStylized viewModelScope.launch { diff --git a/app/src/main/res/font/atkinson_hyperlegible.xml b/app/src/main/res/font/atkinson_hyperlegible.xml new file mode 100644 index 000000000..e3ca41fba --- /dev/null +++ b/app/src/main/res/font/atkinson_hyperlegible.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/src/main/res/font/atkinson_hyperlegible_bold.ttf b/app/src/main/res/font/atkinson_hyperlegible_bold.ttf new file mode 100644 index 000000000..ca3f61384 Binary files /dev/null and b/app/src/main/res/font/atkinson_hyperlegible_bold.ttf differ diff --git a/app/src/main/res/font/atkinson_hyperlegible_regular.ttf b/app/src/main/res/font/atkinson_hyperlegible_regular.ttf new file mode 100644 index 000000000..b3cc4200f Binary files /dev/null and b/app/src/main/res/font/atkinson_hyperlegible_regular.ttf differ diff --git a/app/src/main/res/font/lexend_variable.ttf b/app/src/main/res/font/lexend_variable.ttf new file mode 100644 index 000000000..f70999106 Binary files /dev/null and b/app/src/main/res/font/lexend_variable.ttf differ diff --git a/app/src/main/res/font/noto_sans_variable.ttf b/app/src/main/res/font/noto_sans_variable.ttf new file mode 100644 index 000000000..75575046c Binary files /dev/null and b/app/src/main/res/font/noto_sans_variable.ttf differ diff --git a/app/src/main/res/font/nunito_sans_variable.ttf b/app/src/main/res/font/nunito_sans_variable.ttf new file mode 100644 index 000000000..ccc856573 Binary files /dev/null and b/app/src/main/res/font/nunito_sans_variable.ttf differ diff --git a/app/src/main/res/font/quicksand_variable.ttf b/app/src/main/res/font/quicksand_variable.ttf new file mode 100644 index 000000000..8cd9133bc Binary files /dev/null and b/app/src/main/res/font/quicksand_variable.ttf differ diff --git a/app/src/main/res/font/roboto_condensed_variable.ttf b/app/src/main/res/font/roboto_condensed_variable.ttf new file mode 100644 index 000000000..221055572 Binary files /dev/null and b/app/src/main/res/font/roboto_condensed_variable.ttf differ diff --git a/app/src/main/res/font/rubik_variable.ttf b/app/src/main/res/font/rubik_variable.ttf new file mode 100644 index 000000000..a59aeb632 Binary files /dev/null and b/app/src/main/res/font/rubik_variable.ttf differ diff --git a/app/src/main/res/font/varela_round_regular.ttf b/app/src/main/res/font/varela_round_regular.ttf new file mode 100644 index 000000000..3a54b78fb Binary files /dev/null and b/app/src/main/res/font/varela_round_regular.ttf differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 01c0af6c8..1c7b1ee4d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -116,6 +116,7 @@ Subtitle Size Subtitle Color Subtitle Style + Subtitle Font Subtitle Position Auto-Play Next Autoplay @@ -161,9 +162,10 @@ Text size for subtitles Text color for subtitles Bold, Normal, or Background style for subtitles + Typeface used during playback. Bundled fonts override embedded ASS/SSA fonts so your choice is always visible. Vertical position for subtitles Stylized Subtitles - Honor embedded styles from ASS/SSA subtitles. When off, all subtitles use your size, color, and style settings. + Honor embedded ASS/SSA styles when using the System font. Bundled font choices override embedded styling. Start next episode automatically Off opens the source picker on Play Min quality for auto-play diff --git a/app/src/test/kotlin/com/arflix/tv/ui/screens/player/SubtitleFontOptionTest.kt b/app/src/test/kotlin/com/arflix/tv/ui/screens/player/SubtitleFontOptionTest.kt new file mode 100644 index 000000000..a7cbc75d7 --- /dev/null +++ b/app/src/test/kotlin/com/arflix/tv/ui/screens/player/SubtitleFontOptionTest.kt @@ -0,0 +1,55 @@ +package com.arflix.tv.ui.screens.player + +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +class SubtitleFontOptionTest { + + @Test + fun unknownOrMissingPreferenceFallsBackToSystem() { + assertThat(SubtitleFontOption.fromPreference(null)).isEqualTo(SubtitleFontOption.SYSTEM) + assertThat(SubtitleFontOption.fromPreference("Removed font")).isEqualTo(SubtitleFontOption.SYSTEM) + } + + @Test + fun cyclesThroughEveryBundledFontAndWrapsToSystem() { + val sequence = buildList { + var current = SubtitleFontOption.DefaultPreference + repeat(SubtitleFontOption.entries.size) { + current = SubtitleFontOption.nextPreference(current) + add(current) + } + } + + assertThat(sequence).containsExactly( + "Noto Sans", + "Atkinson Hyperlegible", + "Lexend", + "Roboto Condensed", + "Nunito Sans", + "Quicksand", + "Rubik", + "Varela Round", + "System", + ).inOrder() + } + + @Test + fun everyStoredValueRoundTrips() { + SubtitleFontOption.entries.forEach { option -> + assertThat(SubtitleFontOption.fromPreference(option.preferenceValue)).isEqualTo(option) + } + } + + @Test + fun previousFromSystemWrapsToVarelaRound() { + assertThat(SubtitleFontOption.previousPreference("System")).isEqualTo("Varela Round") + } + + @Test + fun customFontOverridesEmbeddedAssFontStyling() { + assertThat(shouldPreserveEmbeddedSubtitleStyles("Nunito Sans", true)).isFalse() + assertThat(shouldPreserveEmbeddedSubtitleStyles("System", true)).isTrue() + assertThat(shouldPreserveEmbeddedSubtitleStyles("System", false)).isFalse() + } +}