كيف يمكنني أن أرث إعداد النظام المضاد للاسم المستعار لرسم النص على الصور الموجودة خارج الشاشة مثلما يفعل التأرجح؟

StackOverflow https://stackoverflow.com/questions/1910964

  •  19-09-2019
  •  | 
  •  

سؤال

عندما أقوم بتشغيل تطبيقات واجهة المستخدم الرسومية المتأرجحة ضمن Java 6، فإنها تستخدم تلقائيًا إعدادات مكافحة الاسم المستعار للبكسل الفرعي التي تم تكوينها لجميع الخطوط.تم تحسين النتيجة كثيرًا مقارنة بخيارات AA القياسية.

ولكن عندما أرسم على صورة ما، لا أجد طريقة لتهيئة سياق الرسومات لاستخدام تكوين AA الخاص بالنظام.تعد محاولة التلاعب بتلميحات AA المختلفة في Java سببًا خاسرًا لأنه لن تعمل طريقة البكسل الفرعي مع جميع المستخدمين.

هل هناك أي طريقة لوراثة إعدادات AA للنظام لسياق رسومات معين بدلاً من الاضطرار إلى اختيار واحد وتعيين التلميح بشكل صريح؟في الوقت الحالي، لا بد لي من استخدام GASP AA لتجنب النتائج الرهيبة التي يعطيها AA القياسي مع الخطوط الصغيرة.لقد حاولت عدم تعيين أي شيء للنص AA، وعدم تعيين أي تلميحات AA على الإطلاق.


تحديث 2010-01-05

أعتقد أنني قمت بتثبيت هذا؛يبدو أن تلميحات البكسل الفرعي AA يتم احترامها فقط عند الرسم مباشرةً على سياق رسومات AWT؛عندما أرسم على صورة ذات مخزن مؤقت مزدوج، فإنها تقوم فقط بعمل AA قياسي؛ولكن عندما أتجاوز الصورة ذات المخزن المؤقت المزدوج، يتم الانتهاء من البكسل الفرعي AA.

وإلا فإن إجابة The_Fire ستعمل في JVMs التي يتوفر بها Swing (ولكن ليس J2ME JVMs)؛لاحظ أن إجابة The_Fire لا تعمل باستخدام مكون AWT (يفشل استخدام new Label() بدلاً من JLabel() الجديد)، ربما لأنه لا يمكن استخراج FontRenderContext حتى يتم عرض المكون على الشاشة.


يبدو الكود الحالي الخاص بي للحصول على سياق الرسومات لصورتي المستهدفة حاليًا كما يلي:

try {
    if((dbImage=dctRoot.createImage(wid,hgt,1))!=null) {            // if createImage returns null or throws an exception the component is not yet displayable
        dbGraphics=(Graphics2D)dbImage.getGraphics();
        if(dctRoot.properties.getBoolean("Antialias",true)) {
            try {
                // set AA on overall
                dbGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING     ,RenderingHints.VALUE_ANTIALIAS_ON);
                // set text AA to platform/impl default
                dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
                // try to override platform/impl AA with font-specified AA (Java 6+)
                try { dbGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.class.getField("VALUE_TEXT_ANTIALIAS_GASP").get(null)); } catch(Throwable thr) {;} // yes, ignore exception
                }
            catch(Throwable thr) {
                dctRoot.log.println("Antialiasing not supported on this JVM ("+thr+").");
                dctRoot.setProperty("Antialias","False");           // turn off AA for subsequent painting
                }
            }
        }
    }
catch(Throwable thr) {
    dbImage=null;
    dbGraphics=null;
    }

يستخدم الكود الخاص بإنشاء الصورة مكون AWT أساسيًا، والذي يشكل الخلفية التي أرسم عليها كل رسوماتي - المكون عبارة عن لوحة، لأنني بحاجة إلى أن أكون قادرًا على عمل setFocusCycleRoot بحيث يعمل بشكل جيد مع مكونات AWT الأخرى.رمز إنشاء الصورة كما يلي:

public DctImage createImage(int wid, int hgt, float accpty) {
    GraphicsConfiguration               cfg=awtComponent.getGraphicsConfiguration();
    Image                               img=null;

    if(transparentImages) {
        //y { img=new BufferedImage(wid,hgt,BufferedImage.TYPE_INT_ARGB); }     // NB: J2ME CDC/PP 1.1 does not have the BufferedImage constructors (one day I may discover a way to create a BufferedImage via another API!!)
        try { img=cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT); }// NB: J2ME CDC/PP 1.1 does not have this API, but prefer to use GraphicsConfiguration over new BufferImage(...)
        catch(NoClassDefFoundError   thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        catch(NoSuchMethodError      thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        catch(NoSuchFieldError       thr) { transparentImages=false; createImage(wid,hgt,accpty); } // try again with transparency disabled
        }
    else {
        img=cfg.createCompatibleImage(wid,hgt);
        }

    if(accpty>0 && SET_ACCELERATION_PRIORITY!=null) {
        try { SET_ACCELERATION_PRIORITY.invoke(img,new Object[]{new Float(accpty)}); } catch(Throwable thr) {;}
        }

    return (img==null ? null : new DctImage(img));
    }
هل كانت مفيدة؟

المحلول

لقد وجدت أن هناك بعض العوامل التي تحدث هنا.

أولاً، يجب إنشاء الصورة من مكون AWT الأساسي، ويجب إنشاؤها بدون شفافية:

cfg.createCompatibleImage(wid,hgt);

بدلاً من

cfg.createCompatibleImage(wid,hgt,Transparency.TRANSLUCENT);

ثانيًا، لسبب لا يمكن تفسيره، يجب إيقاف إعداد AA الأساسي، KEY_ANTIALIASING، لاستخدام وحدة البكسل الفرعية LCD AA.

وأخيرًا، والأهم من ذلك، يمكن بسهولة استرداد تلميحات عرض خط سطح المكتب باستخدام:

java.awt.Toolkit.getDesktopProperty("awt.font.desktophints")

تحديث 2010-01-05

عند إعادة الاختبار في Java 6.26، يبدو أن مشكلة الحاجة إلى إيقاف تشغيل AA العام لعرض النص AA قد تم حلها أخيرًا (طريقة الانتقال إلى Oracle...بعد أن كان صن مجرد بضع سنوات عشر سنوات متأخرة جداً).

نصائح أخرى

باستخدام Swing، أستطيع الحصول على تلميح تنعيم النص الصحيح مثل هذا:

JLabel label = new JLabel();
FontMetrics fm  = label.getFontMetrics( label.getFont() );
Object aaHintValue = fm.getFontRenderContext().getAntiAliasingHint();

على نظامي يعود هذا RenderingHits.VALUE_TEXT_ANTIALIAS_LCD_HRGB.

يبدو أن java.awt.Toolkit.getDesktopProperty("awt.font.desktophints") فارغة على نظام التشغيل Linux، على الأقل بدون أي خيارات خاصة لسطر أوامر vm، ربما لأنه غير قادر على معرفة الإعدادات الافتراضية للنظام الأساسي.يبدو أن إضافة "-Dawt.useSystemAAFontSettings=lcd" على سبيل المثال يعالج المشكلة ويتيح عرض البكسل الفرعي إذا قمت بتعيين التلميحات على مثيل Graphics2D الخاص بك.

انتظر، هل تقوم بتشغيل هذا الرمز على Windows JVM؟اعتقدت أن ClearType هي إحدى تقنيات Microsoft التي يرثها Swing من خلال بعض التعليمات البرمجية الأصلية (أي غير متوفرة على نظام التشغيل Linux أو الأنظمة الأساسية الأخرى غير التابعة لشركة Microsoft).

لقد قمت ذات مرة بكتابة servlet الذي قام بإنشاء ملفات JPG بخطوط مصقولة تعمل على دبيان، وكان هذا هو الكود الذي استخدمته

Font font = new Font("Komix", Font.PLAIN, 8);
Graphics2D g2;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
FontRenderContext  frc = g2.getFontRenderContext();
g2.setFont(font);
g2.setPaint(Color.black);
g2.drawString(sMessage, xOffset, yOffset);

لا أستطيع أن أتذكر ما إذا كان أي من هذه التعليمات البرمجية يعتمد على Swing (لقد قمت باستيراد javax.swing ويبلغ طول servlet حوالي 300 سطر، لذلك ربما اعتقدت أنني بحاجة إليه لشيء آخر)، يبدو الفحص السريع على Google هكذا موجود بشكل مباشر في مساحة AWT.امل ان يساعد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top