JDK-8175802 : WebView fonts appear as Gibberish on Mac
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: os_x
  • CPU: generic
  • Submitted: 2017-02-22
  • Updated: 2017-02-24
  • Resolved: 2017-02-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8-poolResolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_11"
Java(TM) SE Runtime Environment (build 1.8.0_11-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
OS X 10.11.5  (And likely all versions of OS X)

A DESCRIPTION OF THE PROBLEM :
In some cases text appears as gibberish in the webview when specifying font-family names specifically in CSS.  This occurs when loading Google Maps into a web view.

E.g. when we have
font-family: Roboto, Arial, Sans-serif

The text is gibberish.

But if we change it to 

font-family: Sans-serif

The text is fine.

This problem and workarounds is described in these Stack Overflow posts

http://stackoverflow.com/questions/41602344/strange-chracters-in-google-maps-api-using-java-webview
http://stackoverflow.com/questions/41952734/javafx-webview-font-issue-on-mac

For google maps I was able to work around this by adding the following CSS directive:


.gm-style-mtc > div, .gm-style > div, .gm-style-cc > div, .gm-style, .gm-err-message, .gm-err-title {font-family:sans-serif !important;}

into the style tag of the page.






STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Load Google Maps into a JavaFX webview



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Since the API key is a dummy key, you should see the following error message:

Oops! Something went wrong.
This page didn't load Google Maps correctly. See the JavaScript console for technical details.


ACTUAL -
The error message is gibberish

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

package com.codename1.webview.bugreport;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

/**
 *
 * @author shannah
 */
public class JavaWebviewBugReport extends Application {

    @Override
    public void start(Stage primaryStage) {

        WebView webView = new WebView();
        setPage(webView);
        StackPane root = new StackPane();
        root.getChildren().add(webView);

        Scene scene = new Scene(root, 640, 480);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    void setPage(WebView webView) {
        String html = "<!DOCTYPE html>\n"
                + "  <html>\n"
                + "  <head>\n"
                + "  <meta >\n"
                + "    <title> \"Vista de Clientes\" </title>\n"
                + "\n"
                + "    <style> \n"
                + "    #map {\n"
                + "        height: 100%;\n"
                + "    }\n"
                + "    html, body {\n"
                + "  font-family: sans-serif;\n"
                + "        height: 100%;\n"
                + "        margin: 0;\n"
                + "        padding: 0;\n"
                + "    }\n"
                + "\n"
                + "  .controls {\n"
                + "  margin-top: 10px;\n"
                + "  border: 1px solid transparent;\n"
                + "  border-radius: 2px 0 0 2px;\n"
                + "  box-sizing: border-box;\n"
                + "  -moz-box-sizing: border-box;\n"
                + "  height: 32px;\n"
                + "  outline: none;\n"
                + "  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);\n"
                + "  }\n"
                + "\n"
                + "  #pac-input {\n"
                + "  background-color: #fff;\n"
                + "  font-family: Roboto;\n"
                + "  font-size: 15px;\n"
                + "  font-weight: 300;\n"
                + "  margin-left: 12px;\n"
                + "  padding: 0 11px 0 13px;\n"
                + "  text-overflow: ellipsis;\n"
                + "  width: 300px;\n"
                + "  }\n"
                + "\n"
                + "  #pac-input:focus {\n"
                + "  border-color: #4d90fe;\n"
                + "  }\n"
                + "\n"
                + "  .pac-container {\n"
                + "  font-family: Roboto;\n"
                + "  }\n"
                + "\n"
                + "  #type-selector {\n"
                + "  color: #fff;\n"
                + "  background-color: #4d90fe;\n"
                + "  padding: 5px 11px 0px 11px;\n"
                + "  }\n"
                + "\n"
                + "  #type-selector label {\n"
                + "  font-family: Roboto;\n"
                + "  font-size: 13px;\n"
                + "  font-weight: 300;\n"
                + "  }\n"
                + "  #target {\n"
                + "  width: 345px;\n"
                + "  }\n"
                + "    </style>\n"
                + "  </head>\n"
                + "  <body>\n"
                + "\n"
                + "  <input id=\"pac-input\" class=\"controls\" type=\"text\" placeholder=\"Search Box\">\n"
                + "  <h1> hola </h1>\n"
                + "    <div id=\"map\"></div>\n"
                + "\n"
                + "    <script type=\"text/javascript\" src=\"https://maps.googleapis.com/maps/api/js?key=APIKEYISGOOD&libraries=places\"></script>\n"
                + "\n"
                + "  <script>\n"
                + "\n"
                + "\n"
                + "\n"
                + "  // object for the stores\n"
                + "  var GreenCircle = {\n"
                + "  path: google.maps.SymbolPath.CIRCLE,\n"
                + "  fillColor: 'Lime',\n"
                + "  fillOpacity: 1,\n"
                + "  scale: 10,\n"
                + "  strokeColor: 'green',\n"
                + "  strokeWeight: 1\n"
                + "  }; \n"
                + "\n"
                + "  // google map instance\n"
                + "  var map;\n"
                + "  var markers = [];\n"
                + "\n"
                + "  // function for the initialization\n"
                + "  function initMap() {\n"
                + "  map = new google.maps.Map(document.getElementById('map'), {\n"
                + "  zoom: 12,\n"
                + "  center: {lat: 21.8857199, lng: -102.3613399}\n"
                + "  });\n"
                + "\n"
                + "  var input = document.getElementById('pac-input');\n"
                + "  var searchBox = new google.maps.places.SearchBox(input);\n"
                + "  map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);\n"
                + "\n"
                + "  // Bias the SearchBox results towards current map's viewport.\n"
                + "  map.addListener('bounds_changed', function() {\n"
                + "  searchBox.setBounds(map.getBounds());\n"
                + "  });\n"
                + "\n"
                + "\n"
                + "  searchBox.addListener('places_changed', function() {\n"
                + "  var places = searchBox.getPlaces();\n"
                + "\n"
                + "  if (places.length == 0) {\n"
                + "  return;\n"
                + "  }\n"
                + "\n"
                + "\n"
                + "  // Clear out the old markers.\n"
                + "  markers.forEach(function(marker) {\n"
                + "  marker.setMap(null);\n"
                + "  });\n"
                + "  markers = [];\n"
                + "\n"
                + "  // For each place, get the icon, name and location.\n"
                + "  var bounds = new google.maps.LatLngBounds();\n"
                + "  places.forEach(function(place) {\n"
                + "  if (!place.geometry) {\n"
                + "  console.log(\"Returned place contains no geometry\");\n"
                + "  return;\n"
                + "  }\n"
                + "\n"
                + "  var icon = {\n"
                + "  url: place.icon,\n"
                + "  size: new google.maps.Size(71, 71),\n"
                + "  origin: new google.maps.Point(0, 0),\n"
                + "  anchor: new google.maps.Point(17, 34),\n"
                + "  scaledSize: new google.maps.Size(25, 25)\n"
                + "  };\n"
                + "\n"
                + "  // Create a marker for each place.\n"
                + "  markers.push(new google.maps.Marker({\n"
                + "  map: map,\n"
                + "  icon: icon,\n"
                + "  title: place.name,\n"
                + "  position: place.geometry.location,\n"
                + "  draggable: true\n"
                + "  }));\n"
                + "\n"
                + "  if (place.geometry.viewport) {\n"
                + "  // Only geocodes have viewport.\n"
                + "  bounds.union(place.geometry.viewport);\n"
                + "  } else {\n"
                + "  bounds.extend(place.geometry.location);\n"
                + "  }\n"
                + "  });\n"
                + "  map.fitBounds(bounds);\n"
                + "  }); \n"
                + "  }\n"
                + "\n"
                + "    initMap();\n"
                + "\n"
                + "    function setMarker(latvar, lngvar, labels){\n"
                + "  var marker = new google.maps.Marker({ \n"
                + "  position: { lat: latvar, lng: lngvar},\n"
                + "  map: map,\n"
                + "  label: labels || \"\",\n"
                + "  tittle: labels,\n"
                + "  icon: GreenCircle\n"
                + "  });\n"
                + "    }\n"
                + "\n"
                + "  function setSelfMarker(Geojson)\n"
                + "  {\n"
                + "  map.data.addGeoJson( JSON.parse(Geojson) );\n"
                + "  }\n"
                + "\n"
                + "  function setPosition(lat, lng)\n"
                + "  {\n"
                + "  map.setCenter(new google.maps.LatLng( lat, lng ) );\n"
                + "  }\n"
                + "\n"
                + "    </script>\n"
                + "\n"
                + "\n"
                + "  </body>\n"
                + "  </html>";
        webView.getEngine().loadContent(html);

    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Add the following CSS directive into the style tag:

.gm-style-mtc > div, .gm-style > div, .gm-style-cc > div, .gm-style, .gm-err-message, .gm-err-title {font-family:sans-serif !important;}

The test case then becomes

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.codename1.webview.bugreport;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

/**
 *
 * @author shannah
 */
public class JavaWebviewBugReport extends Application {

    @Override
    public void start(Stage primaryStage) {

        WebView webView = new WebView();
        setPage(webView);
        StackPane root = new StackPane();
        root.getChildren().add(webView);

        Scene scene = new Scene(root, 640, 480);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    void setPage(WebView webView) {
        String html = "<!DOCTYPE html>\n"
                + "  <html>\n"
                + "  <head>\n"
                + "  <meta >\n"
                + "    <title> \"Vista de Clientes\" </title>\n"
                + "\n"
                + "    <style> .gm-style-mtc > div, .gm-style > div, .gm-style-cc > div, .gm-style, .gm-err-message, .gm-err-title {font-family:sans-serif !important;}\n"
                + "    #map {\n"
                + "        height: 100%;\n"
                + "    }\n"
                + "    html, body {\n"
                + "  font-family: sans-serif;\n"
                + "        height: 100%;\n"
                + "        margin: 0;\n"
                + "        padding: 0;\n"
                + "    }\n"
                + "\n"
                + "  .controls {\n"
                + "  margin-top: 10px;\n"
                + "  border: 1px solid transparent;\n"
                + "  border-radius: 2px 0 0 2px;\n"
                + "  box-sizing: border-box;\n"
                + "  -moz-box-sizing: border-box;\n"
                + "  height: 32px;\n"
                + "  outline: none;\n"
                + "  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);\n"
                + "  }\n"
                + "\n"
                + "  #pac-input {\n"
                + "  background-color: #fff;\n"
                + "  font-family: Roboto;\n"
                + "  font-size: 15px;\n"
                + "  font-weight: 300;\n"
                + "  margin-left: 12px;\n"
                + "  padding: 0 11px 0 13px;\n"
                + "  text-overflow: ellipsis;\n"
                + "  width: 300px;\n"
                + "  }\n"
                + "\n"
                + "  #pac-input:focus {\n"
                + "  border-color: #4d90fe;\n"
                + "  }\n"
                + "\n"
                + "  .pac-container {\n"
                + "  font-family: Roboto;\n"
                + "  }\n"
                + "\n"
                + "  #type-selector {\n"
                + "  color: #fff;\n"
                + "  background-color: #4d90fe;\n"
                + "  padding: 5px 11px 0px 11px;\n"
                + "  }\n"
                + "\n"
                + "  #type-selector label {\n"
                + "  font-family: Roboto;\n"
                + "  font-size: 13px;\n"
                + "  font-weight: 300;\n"
                + "  }\n"
                + "  #target {\n"
                + "  width: 345px;\n"
                + "  }\n"
                + "    </style>\n"
                + "  </head>\n"
                + "  <body>\n"
                + "\n"
                + "  <input id=\"pac-input\" class=\"controls\" type=\"text\" placeholder=\"Search Box\">\n"
                + "  <h1> hola </h1>\n"
                + "    <div id=\"map\"></div>\n"
                + "\n"
                + "    <script type=\"text/javascript\" src=\"https://maps.googleapis.com/maps/api/js?key=APIKEYISGOOD&libraries=places\"></script>\n"
                + "\n"
                + "  <script>\n"
                + "\n"
                + "\n"
                + "\n"
                + "  // object for the stores\n"
                + "  var GreenCircle = {\n"
                + "  path: google.maps.SymbolPath.CIRCLE,\n"
                + "  fillColor: 'Lime',\n"
                + "  fillOpacity: 1,\n"
                + "  scale: 10,\n"
                + "  strokeColor: 'green',\n"
                + "  strokeWeight: 1\n"
                + "  }; \n"
                + "\n"
                + "  // google map instance\n"
                + "  var map;\n"
                + "  var markers = [];\n"
                + "\n"
                + "  // function for the initialization\n"
                + "  function initMap() {\n"
                + "  map = new google.maps.Map(document.getElementById('map'), {\n"
                + "  zoom: 12,\n"
                + "  center: {lat: 21.8857199, lng: -102.3613399}\n"
                + "  });\n"
                + "\n"
                + "  var input = document.getElementById('pac-input');\n"
                + "  var searchBox = new google.maps.places.SearchBox(input);\n"
                + "  map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);\n"
                + "\n"
                + "  // Bias the SearchBox results towards current map's viewport.\n"
                + "  map.addListener('bounds_changed', function() {\n"
                + "  searchBox.setBounds(map.getBounds());\n"
                + "  });\n"
                + "\n"
                + "\n"
                + "  searchBox.addListener('places_changed', function() {\n"
                + "  var places = searchBox.getPlaces();\n"
                + "\n"
                + "  if (places.length == 0) {\n"
                + "  return;\n"
                + "  }\n"
                + "\n"
                + "\n"
                + "  // Clear out the old markers.\n"
                + "  markers.forEach(function(marker) {\n"
                + "  marker.setMap(null);\n"
                + "  });\n"
                + "  markers = [];\n"
                + "\n"
                + "  // For each place, get the icon, name and location.\n"
                + "  var bounds = new google.maps.LatLngBounds();\n"
                + "  places.forEach(function(place) {\n"
                + "  if (!place.geometry) {\n"
                + "  console.log(\"Returned place contains no geometry\");\n"
                + "  return;\n"
                + "  }\n"
                + "\n"
                + "  var icon = {\n"
                + "  url: place.icon,\n"
                + "  size: new google.maps.Size(71, 71),\n"
                + "  origin: new google.maps.Point(0, 0),\n"
                + "  anchor: new google.maps.Point(17, 34),\n"
                + "  scaledSize: new google.maps.Size(25, 25)\n"
                + "  };\n"
                + "\n"
                + "  // Create a marker for each place.\n"
                + "  markers.push(new google.maps.Marker({\n"
                + "  map: map,\n"
                + "  icon: icon,\n"
                + "  title: place.name,\n"
                + "  position: place.geometry.location,\n"
                + "  draggable: true\n"
                + "  }));\n"
                + "\n"
                + "  if (place.geometry.viewport) {\n"
                + "  // Only geocodes have viewport.\n"
                + "  bounds.union(place.geometry.viewport);\n"
                + "  } else {\n"
                + "  bounds.extend(place.geometry.location);\n"
                + "  }\n"
                + "  });\n"
                + "  map.fitBounds(bounds);\n"
                + "  }); \n"
                + "  }\n"
                + "\n"
                + "    initMap();\n"
                + "\n"
                + "    function setMarker(latvar, lngvar, labels){\n"
                + "  var marker = new google.maps.Marker({ \n"
                + "  position: { lat: latvar, lng: lngvar},\n"
                + "  map: map,\n"
                + "  label: labels || \"\",\n"
                + "  tittle: labels,\n"
                + "  icon: GreenCircle\n"
                + "  });\n"
                + "    }\n"
                + "\n"
                + "  function setSelfMarker(Geojson)\n"
                + "  {\n"
                + "  map.data.addGeoJson( JSON.parse(Geojson) );\n"
                + "  }\n"
                + "\n"
                + "  function setPosition(lat, lng)\n"
                + "  {\n"
                + "  map.setCenter(new google.maps.LatLng( lat, lng ) );\n"
                + "  }\n"
                + "\n"
                + "    </script>\n"
                + "\n"
                + "\n"
                + "  </body>\n"
                + "  </html>";
        webView.getEngine().loadContent(html);

    }
}



Comments
To Submitter: Its fixed in JDK 9 early access [jdk-ea+157]. Please verify the issue by downloading JDK 9 from below link: https://jdk9.java.net/download/
24-02-2017

Below are the results: 8u121 :: FAIL 8u152 :: FAIL 9-ea+143 :: FAIL 9-ea+146 :: FAIL 9-ea+147:: FAIL 9-ea+148 ::PASS 9-ea+149 ::PASS 9+ea-157 ::PASS
24-02-2017

Changing priority to P3 as this has been opened on StackOverFlow: http://stackoverflow.com/questions/41602344/strange-chracters-in-google-maps-api-using-java-webview http://stackoverflow.com/questions/41952734/javafx-webview-font-issue-on-mac
23-02-2017